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;
}