分析:
先随机出一个
n/2
的情况出来,期望步数是
2nCn/2n
.
把其中一个位翻转,相同的个数要么为n / 2 + 1,要么为n/2 -1,显示结果都是0.如果把其中两位翻转结果就有n/2 + 2, n/2, n/2-2三种情况,第二种是可以鉴别的。
利用这个关系可以枚举其中任意一个是0或者1,找其它n -1个位和它的二元组的情况来求得关系即可。
第二种的步数是
n+1
。
注意,交互题要cout << endl;这种刷新输出缓冲区的。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <ctime>
using namespace std;
#define pr(x) cout << #x << ": " << x << " "
#define pl(x) cout << #x << ": " << x << endl;
struct jibancanyang
{
bool A[1001], B[1001];
int n;
void show(bool a[], int k = 0) {
a[k] = !a[k];
for (int i = 1; i <= n; ++i) putchar(a[i] ? '1' : '0');
a[k] = !a[k];
cout << endl;
}
void fun() {
scanf("%d", &n);
srand(time(NULL));
while (true) {
for (int i = 1; i <= n; ++i) A[i] = rand() % 2;
show(A);
int x; scanf("%d", &x);
if (x == n / 2) break;
if (x == n) return;
}
A[1] = !A[1];
for (int i = 2; i <= n; ++i) {
show(A, i);
int x; scanf("%d", &x);
if (x == n) return ;
if (x == n / 2) B[i] = false;
else B[i] = true;
}
putchar(A[1] ? '1' : '0');
for (int i = 2; i <= n; ++i) {
if (B[i]) putchar(!A[i] ? '1' : '0');
else putchar(A[i] ? '1' : '0');
}
cout << endl;
int x; scanf("%d", &x);
if (x == n) return ;
putchar(!A[1] ? '1' : '0');
for (int i = 2; i <= n; ++i) {
if (B[i]) putchar(A[i] ? '1' : '0');
else putchar(!A[i] ? '1' : '0');
}
cout << endl;
scanf("%d", &x);
}
}ac;
int main()
{
#ifdef LOCAL
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
ac.fun();
return 0;
}