Live2d Test Env

Gym - 100851J: Jump(交互+构造+(大胆瞎搞)))

题意:给定长度为N的01串,现在让你猜这个串,猜的次数要不超过N+500次。 每次你猜一个串,系统会返回N/2,或N,或0。当且当有N/2个位置猜对,N个位置猜对,其他。

思路:因为信息不多,没有关联性,所以前期只有瞎猜,直到猜到一个N/2,(如果是N也ok)。猜到N/2之后,我们从这个N/2串考虑,有一半的位置是对的,有一半的位置是错的,那么我们先把第一位取反,后面挨个去取反验证,假设取反第i位,输出N/2,说明第i位和第1位正确性相反,否则相同。那么验证完后,只有两种情况,第一位是对的,第一位是错的,把两种情况带入验证,其中一个是N。

(根据题意,500次以内大概率会出现一个N/2;网上说50次就会出现一个。

(输出换行符自带缓冲,不需要再fflush(stdout)。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
string s,fcy; int same[maxn];
int main()
{
    int N,i,j,ans;
    scanf("%d",&N);
    while(true){
        s="";
        for(i=0;i<N;i++) {
            char c='1'; int num=rand()%2;
            s+=(c-num);
        }
        cout<<s<<endl;
        cin>>ans; same[0]=1;
        if(ans==N) break;
        if(ans==N/2) {
            string tmp=s;
            tmp[0]=1-(s[0]-'0')+'0';
            for(i=1;i<N;i++) {
                tmp[i]=1-(s[i]-'0')+'0';
                cout<<tmp<<endl;
                cin>>ans;
                if(ans==N) return 0;
                if(ans==0) same[i]=1;
                tmp[i]=s[i];
            }
        }
        for(i=0;i<N;i++) if(same[i]) s[i]=1-(s[i]-'0')+'0';
        cout<<s<<endl;
        cin>>ans;
        if(ans==N) break;
        for(i=0;i<N;i++) s[i]=1-(s[i]-'0')+'0';
        cout<<s<<endl;
        cin>>ans;
        if(ans==N) break;
    }
    return 0;
}

 

posted @ 2018-08-13 08:31  nimphy  阅读(267)  评论(0编辑  收藏  举报