Codeforces Round #676 (Div. 2) E待補

2020-10-21 12:00:32

「樓下一個男人病得要死,那間隔壁的一家唱著留聲機,對面是弄孩子。樓上有兩人狂笑;還有打牌聲。河中的船上有女人哭著她死去的母親。人類的悲歡並不相通,我只覺得他們吵鬧。」

A - XORwice

把a和b看成二進位制數處理,不難發現只要a,b某位都是1我們就有辦法把它消掉,否則答案該位一定是a+b(0,1)該位的值

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int main()
{
    IO;
    int T=1;
    cin>>T;
    while(T--)
    {
        int a,b;
        cin>>a>>b;
        int res=0;
        for(int i=30;i>=0;i--)
            if(!(a>>i&1)&&(b>>i&1)||(a>>i&1)&&!(b>>i&1)) 
                res+=1<<i;
        cout<<res<<'\n';
    }
    return 0;
}

B - Putting Bricks in the Wall

我們只要讓g[1][2]g[2][1]的值相等並且不等於g[n][n-1]g[n-1][n]的值即可,最多操作3步。

懶得想了,直接列舉( 2 4 = 16 2^4=16 24=16),應該有更好寫的寫法。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=210;
char g[N][N];
int main()
{
    IO;
    int T=1;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++) cin>>g[i]+1;
        if(g[1][2]=='0'&&g[2][1]=='0'&&g[n][n-1]=='0'&&g[n-1][n]=='0') 
            cout<<2<<'\n'<<1<<' '<<2<<'\n'<<2<<' '<<1<<'\n';
        else if(g[1][2]=='1'&&g[2][1]=='0'&&g[n][n-1]=='0'&&g[n-1][n]=='0')
            cout<<1<<'\n'<<2<<' '<<1<<'\n';
        else if(g[1][2]=='0'&&g[2][1]=='1'&&g[n][n-1]=='0'&&g[n-1][n]=='0')
            cout<<1<<'\n'<<1<<' '<<2<<'\n';
        else if(g[1][2]=='1'&&g[2][1]=='1'&&g[n][n-1]=='0'&&g[n-1][n]=='0')
            cout<<0<<'\n';
        else if(g[1][2]=='0'&&g[2][1]=='0'&&g[n][n-1]=='1'&&g[n-1][n]=='0')
            cout<<1<<'\n'<<n-1<<' '<<n<<'\n';
        else if(g[1][2]=='1'&&g[2][1]=='0'&&g[n][n-1]=='1'&&g[n-1][n]=='0')
            cout<<2<<'\n'<<2<<' '<<1<<'\n'<<n<<' '<<n-1<<'\n';
        else if(g[1][2]=='0'&&g[2][1]=='1'&&g[n][n-1]=='1'&&g[n-1][n]=='0')
            cout<<2<<'\n'<<2<<' '<<1<<'\n'<<n<<' '<<n-1<<'\n';
        else if(g[1][2]=='1'&&g[2][1]=='1'&&g[n][n-1]=='1'&&g[n-1][n]=='0')
            cout<<1<<'\n'<<n<<' '<<n-1<<'\n';
        else if(g[1][2]=='0'&&g[2][1]=='0'&&g[n][n-1]=='0'&&g[n-1][n]=='1')
            cout<<1<<'\n'<<n<<' '<<n-1<<'\n';
        else if(g[1][2]=='1'&&g[2][1]=='0'&&g[n][n-1]=='0'&&g[n-1][n]=='1')
            cout<<2<<'\n'<<1<<' '<<2<<'\n'<<n<<' '<<n-1<<'\n';
        else if(g[1][2]=='0'&&g[2][1]=='1'&&g[n][n-1]=='0'&&g[n-1][n]=='1')
            cout<<2<<'\n'<<1<<' '<<2<<'\n'<<n-1<<' '<<n<<'\n';
        else if(g[1][2]=='1'&&g[2][1]=='1'&&g[n][n-1]=='0'&&g[n-1][n]=='1')
            cout<<1<<'\n'<<n-1<<' '<<n<<'\n';
        else if(g[1][2]=='0'&&g[2][1]=='0'&&g[n][n-1]=='1'&&g[n-1][n]=='1')
            cout<<0<<'\n';
        else if(g[1][2]=='1'&&g[2][1]=='0'&&g[n][n-1]=='1'&&g[n-1][n]=='1')
            cout<<1<<'\n'<<1<<' '<<2<<'\n';
        else if(g[1][2]=='0'&&g[2][1]=='1'&&g[n][n-1]=='1'&&g[n-1][n]=='1')
            cout<<1<<'\n'<<2<<' '<<1<<'\n';
        else    
            cout<<2<<'\n'<<1<<' '<<2<<'\n'<<2<<' '<<1<<'\n';
    }
    return 0;

C - Palindromifier

a b c d e f → ( e d c b ) a b c d e f → e d c b a b c d e f ( e d c b a ) → e d c b a b c d e f e d c b a ( b c d e ) abcdef \to (edcb)abcdef\to edcbabcdef(edcba)\to edcbabcdefedcba(bcde) abcdef(edcb)abcdefedcbabcdef(edcba)edcbabcdefedcba(bcde)
只要三步直接搞出來,可以配合程式碼和上述例子食用

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        string s;
        cin>>s;
        int n=s.size();
        cout<<3<<'\n';
        cout<<"L "<<n-1<<'\n';
        cout<<"R "<<n-1<<'\n';
        cout<<"R "<<2*n-1<<'\n';
    }
    
    return 0;
    
}

D - Hexagons

六個方向分別讓座標的變化:
c 1 : ( x + 1 , y + 1 ) c_1:(x+1,y+1) c1:(x+1,y+1)
c 2 : ( x , y + 1 ) c_2:(x,y+1) c2:(x,y+1)
c 3 : ( x − 1 , y ) c_3:(x-1,y) c3:(x1,y)
c 4 : ( x − 1 , y − 1 ) c_4:(x-1,y-1) c4:(x1,y1)
c 5 : ( x , y − 1 ) c_5:(x,y-1) c5:(x,y1)
c 6 : ( x + 1 , y ) c_6:(x+1,y) c6:(x+1,y)

不難發現操作 c 2 + c 6 = c 1 c_2+c_6=c_1 c2+c6=c1 c 3 + c 5 = c 4 c_3+c_5=c_4 c3+c5=c4
因此從兩方面考慮是否使用 c 1 c_1 c1 c 4 c_4 c4操作
如果不使用那麼只通過單獨進行橫座標±1和縱座標±1到達目的地直接算即可。
如果使用那麼首先使得最終向x座標和向y座標移動的步數(dx=dy)相等,於是考慮先通過橫座標±1或者縱座標±1操作使最終dx=dy,然後再通過 c 1 c_1 c1或者 c 4 c_4 c4操作使之到達目的地。
不過注意等效操作 c 2 + c 6 = c 1 c_2+c_6=c_1 c2+c6=c1 c 3 + c 5 = c 4 c_3+c_5=c_4 c3+c5=c4取代價更小的。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
ll c[10];
int main()
{
    IO;
    int T=1;
    cin>>T;
    while(T--)
    {
        ll x,y;
        cin>>x>>y;
        for(int i=1;i<=6;i++) cin>>c[i];
        ll res=8e18;ll now=0;
        // +x 6
        // -x 3
        // +y 2
        // -y 5
        // 不用c1和c4
        if(x>=0&&y>=0)
            now=c[6]*x+c[2]*y;
        else if(x>=0&&y<0)
            now=c[6]*x+c[5]*(-y);
        else if(x<0&&y>=0)
            now=c[3]*(-x)+c[2]*y;
        else
            now=c[3]*(-x)+c[5]*(-y);
        res=min(res,now);
        // 使用c1和c4
        if(x>y)
        {
            now=0;
            now+=c[5]*(x-y);
            
            if(x>=0) now+=min(c[1],c[2]+c[6])*x;
            else now+=min(c[4],c[3]+c[5])*(-x);
            res=min(res,now);
            now=0;
            now+=c[6]*(x-y);
            if(y>=0) now+=min(c[1],c[2]+c[6])*y;
            else now+=min(c[4],c[3]+c[5])*(-y);
            res=min(res,now);
        }
        else
        {
            now=0;
            now+=c[3]*(y-x);
            if(y>=0) now+=min(c[1],c[2]+c[6])*y;
            else now+=min(c[4],c[3]+c[5])*(-y);
            res=min(res,now);
            now=0;
            now+=c[2]*(y-x);
            if(x>=0) now+=min(c[1],c[2]+c[6])*x;
            else now+=min(c[4],c[3]+c[5])*(-x);
            res=min(res,now);
        }
        cout<<res<<'\n';
    }
    return 0;
}

吐槽一波,這題debug了半天竟然是上限搞小了,自己一般開 1 0 18 10^{18} 1018結果有資料的答案比該值還大,最終把最大值開到 8 × 1 0 18 8×10^{18} 8×1018才過的。。。

剛剛看了一波別人的題解,發現D題只需要把所有等效操作的代價取個最小值即可,沒必要這樣討論,嗨自己還是太菜了

E - Swedish Heroes

這題好像是dp,以後回補的!

最近學業壓力有點重,而且快期中考試了。。。這週六還有校賽,希望能打出好成績。