简单的枚举(人机交互题)

Example

input

2

1

0

1

2

output

01

11

10

00

思路:先利用mt19937这个随机数,随机出正确n/2的字符串。

接着,就是比较精妙的地方,用O(n)的复杂度猜出完整的字符串,设我们随机出来正确n/2的字符串是s.

设ans=s

我们先这样考虑,s[0]要么是对的,要么是错的。

假设s[0]是对的,那么对s[0]取反以后,s中正确的只有n/2-1个了,这时,我们将string tmp=s

从 i=1开始,依次猜tmp[i]^=1,也就是将tmp[i]取反以后输出,如果能返回n/2,意味着这一位上s[i]是错误的,因为tmp[i]是正确的,我们将ans[i]也取反(将错的变成对的),所以,这样遍历一遍以后,ans就是最后的正确答案。

假设 s[0]是错的,那么对s[0]取反以后,s中正确的有n/2+1个了,令string tmp=s,

还是从i=1开始,依次对tmp[i]进行取反,一旦满足正确的有n/2个,说明原来的s[i]是正确的,取反以后变成了错误的,所以我们将错就错,将ans[i]也取反,最后得出的ans是全错的,所以在取一次反就可以了。

代码:

#include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    mt19937 mt_rand(time(0));
    string ans;
    cin>>n;
    int tmp;
    while(1)
    {
        ans="";
        for(int i=0;i<n;i++)
        {
            ans.push_back('0'+(mt_rand()&1));
        }
        cout<<ans<<endl;
        cin>>tmp;
        if(tmp==n) return 0;
        if(tmp==n/2) break;
    }
    string ret=ans;
    ans[0]^=1;
    for(int i=1;i<n;i++)
    {
        string s=ans;
        s[i]^=1;
        cout<<s<<endl;
        cin>>tmp;
        if(tmp)
        {
            ret[i]^=1;
        }
    }
    cout<<ret<<endl;
    cin>>tmp;
    if(tmp==n) return 0;
    for(auto &t: ret)
    {
        t^=1;
    }
    cout<<ret<<endl;
    cin>>tmp;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40774175/article/details/84455113