1. 程式人生 > >Codeforces Round #435 (Div. 2) c+d

Codeforces Round #435 (Div. 2) c+d

pan define ons eve vector class bits ace mod

C:給n和k要求,找出n個不同的數,使得亦或起來等於k

可以先預處理從1到1e5,找亦或起來等於(11111111111111111)(二進制)的所有對數,然後四個一起亦或就是0了,再和k亦或

可以看出要分四種情況討論,對於n%4=p的情況,應該找到p-1個不同的數亦或起來等於0,可以小範圍的p-1重循環搜索,對於n%4==2&&x==0的情況要註意特判,可以用6重循環,每層不超過10

代碼過於復雜了,應該可以簡化一下

技術分享
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define
pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-7; const int N=200000+10,maxn=60000+10,inf=0x3f3f3f; bool vis[N];
int main() { // cout<<(0^1^2^4^8^15)<<endl; ios::sync_with_stdio(false); cin.tie(0); int n,x; cin>>n>>x; if(n==2&&x==0) { cout<<"NO"<<endl; return 0; } cout<<"YES"<<endl; vector<int
>v1,v2; for(int i=1;i<(1<<17);i++) { int s=0; for(int j=0;j<17;j++) { if(i&(1<<j)); else s+=(1<<j); } // cout<<i<<" "<<s<<endl; if(!vis[i]&&!vis[s]) { vis[s]=vis[i]=1; v1.pb(i); v2.pb(s); } } if(n%4==2&&x==0) { set<int>ans; int a,b,c,d,e,f; for(int i=0;i<30;i++) { for(int j=i+1;j<30;j++) { for(int k=j+1;k<30;k++) { for(int ii=k+1;ii<30;ii++) { for(int jj=ii+1;jj<30;jj++) { if((i^j^k^ii^jj)!=i&&(i^j^k^ii^jj)!=j &&(i^j^k^ii^jj)!=k&&(i^j^k^ii^jj)!=ii &&(i^j^k^ii^jj)!=jj&&(i^j^k^ii^jj)==0) { ans.insert(i); ans.insert(j); ans.insert(k); ans.insert(ii); ans.insert(jj); ans.insert(0); a=i,b=j,c=k,d=ii,e=jj,f=0; break; } } if(ans.size()!=0)break; } if(ans.size()!=0)break; } if(ans.size()!=0)break; } if(ans.size()!=0)break; } int k=0; for(int i=0;i<v1.size();i++) { if(k>=(n-6)/2)break; if(v1[i]==a||v2[i]==a||v1[i]==b||v2[i]==b|| v1[i]==c||v2[i]==c||v1[i]==d||v2[i]==d|| v1[i]==e||v2[i]==e||v1[i]==f||v2[i]==f)continue; k++; ans.insert(v1[i]); ans.insert(v2[i]); } for(auto x:ans) cout<<x<<" "; cout<<endl; return 0; } set<int>ans; if(n%4==1) { ans.insert(x); int k=0; for(int i=0;i<v1.size();i++) { if(k>=(n-1)/2)break; if(v1[i]==x||v2[i]==x)continue; ans.insert(v1[i]); ans.insert(v2[i]); k++; } } else if(n%4==2) { int a,b; for(int i=0;i<100;i++) { // cout<<(x^i)<<" "<<i<<endl; if((x^i)!=i) { // cout<<(x^i)<<" "<<i<<endl; ans.insert(x^i); ans.insert(i); a=x^i;b=i; break; } } int k=0; for(int i=0;i<v1.size();i++) { if(k>=(n-2)/2)break; if(v1[i]==a||v2[i]==a||v1[i]==b||v2[i]==b)continue; ans.insert(v1[i]); ans.insert(v2[i]); k++; } } else if(n%4==3) { int a,b,c; for(int i=1;i<100;i++) { for(int j=i+1;j<100;j++) { if((x^i^j)!=i&&(x^i^j)!=j) { ans.insert(x^i^j); ans.insert(i); ans.insert(j); a=x^i^j;b=i;c=j; break; } } if(ans.size()!=0)break; } int k=0; for(int i=0;i<v1.size();i++) { if(k>=(n-3)/2)break; if(v1[i]==a||v2[i]==a||v1[i]==b||v2[i]==b||v1[i]==c||v2[i]==c)continue; ans.insert(v1[i]); ans.insert(v2[i]); k++; } } else { int a,b,c,d; for(int i=1;i<100;i++) { for(int j=i+1;j<100;j++) { for(int k=j+1;k<100;k++) { if((x^i^j^k)!=i&&(x^i^j^k)!=j&&(x^i^j^k)!=k) { ans.insert(x^i^j^k); ans.insert(i); ans.insert(j); ans.insert(k); a=x^i^j^k;b=i;c=j;d=k; break; } } if(ans.size()!=0)break; } if(ans.size()!=0)break; } int k=0; for(int i=0;i<v1.size();i++) { if(k>=(n-4)/2)break; if(v1[i]==a||v2[i]==a||v1[i]==b||v2[i]==b||v1[i]==c||v2[i]==c||v1[i]==d||v2[i]==d)continue; ans.insert(v1[i]); ans.insert(v2[i]); k++; } } for(auto x : ans) cout<<x<<" "; cout<<endl; return 0; } /******************** ********************/
C

D:交互題(永遠是二分),有一個長度為n的01字符串,先輸入n,查詢是?+長度為n的01字符串,給出的結果是漢明距離(兩個字符串不同的個數),要求在15次內找到一個0一個1

既然能保證有0和1,那麽可以找到01串或者10串,用二分對於[m,r)如果有01串,那麽l=m,否則r=m

one是1的個數,那麽如何判斷是否有01串呢,構造一個l到r是1的,其他都是0的字符串,假如l到r中只有0,那麽結果就是one+(r-l+1),如果只有1,那麽結果就是one-(r-l+1),這樣有01就是one-(r-l+1)<k<one+(r-l+1)

技術分享
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;

const double g=10.0,eps=1e-7;
const int N=100000+10,maxn=60000+10,inf=0x3f3f3f;

void debug(){cout<<-1<<endl;}

int n,one;
bool ok(int l,int r)
{
    string s=string(n,0);
    for(int i=l;i<=r;i++)
        s[i]=1;
    cout<<"? "<<s<<endl;
    cout.flush();
    int a;
    cin>>a;
    return one-(r-l+1)<a&&a<one+(r-l+1);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    cout<<"? "<<string(n,0)<<endl;
    cout.flush();
    cin>>one;
    int l=0,r=n-1;
    while(l<r-1)
    {
        int m=(l+r)/2;
        if(ok(m,r))l=m;
        else r=m;
    }
    string s=string(n,0);
    s[l]=1;
    cout<<"? "<<s<<endl;
    cout.flush();
    int a;
    cin>>a;
    if(a==one+1)cout<<"! "<<l+1<<" "<<l+2<<endl;
    else cout<<"! "<<l+2<<" "<<l+1<<endl;
    cout.flush();
    return 0;
}
/********************
0011001100
********************/
D

Codeforces Round #435 (Div. 2) c+d