题解:P6982 [NEERC2015] Jump
posted on 2024-11-25 13:21:46 | under | source
萌新做的第一道紫交互题纪念一下。
记串 \(S\) 的 \(k\) 为 \(K(S)\),答案串为 \(A\)。
首先考虑怎么求一个 \(k=\frac n2\) 的串。注意到将某一位取反后 \(k\) 恰好加或减 \(1\),那么可以一开始给出全 \(0\) 串 \(S_0\) 然后进行 \(n\) 次调整变为全 \(1\) 串 \(S_1\),显然 \(K(S_0)+K(S_1)=n\),可以幻想一条折线,起点为 \(K(S_0)\) 终点为 \(K(S_1)\) 那么 \(k=\frac n2\) 的情况一定被折线经过。
于是我们在 \(n+1\) 次步数内求出了 \(k=\frac n2\) 的串 \(P\)。
现在好做了,由于将一个位取反无法得知具体信息,所以将两个位 \(i,j\) 取反,记 \(c_i=[A_i=P_i]\),那么若取反后 \(k\) 仍为 \(\frac n2\) 那么 \(c_i\ne c_j\),反之 \(c_i=c_j\)。固定 \(i\),那么原串被划分为 \(c=c_i\) 和 \(c\ne c_i\) 的两部分,将一部分再取反则所有的 \(c\) 相等。枚举两种情况即可。
上述部分消耗了 \(n+1\) 的步数,总计 \(2n+2\) 无法接受。
需要请出随机化大蛇了!我们可以随机生成一个串来求出 \(P\),生成出来的概率为 \(\frac {n \choose {\frac n2}}{2^n}>0.025\),进行 \(499\) 次仍无法得到 \(P\) 的概率大概是 \(3\times 10^{-6}\),非常渺小。那么总次数可以接受。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, a[N];
bool c[N];
inline bool get(){
for(int i = 1; i <= n; ++i) a[i] = rand() % 2, putchar(a[i] + '0');
putchar('\n');
fflush(stdout);
int k; scanf("%d", &k);
if(k == n / 2) return true;
return false;
}
signed main(){
srand(time(0));
cin >> n;
while(!get());
for(int i = 2; i <= n; ++i){
for(int j = 1; j <= n; ++j)
if(j == 1 || j == i) putchar((a[j] ^ 1) + '0');
else putchar(a[j] + '0');
putchar('\n');
fflush(stdout);
int k; scanf("%d", &k);
c[i] = (k == (n / 2));
}
for(int i = 1; i <= n; ++i)
if(!c[i]) putchar((a[i] ^ 1) + '0');
else putchar(a[i] + '0');
putchar('\n');
fflush(stdout);
int k; scanf("%d", &k);
if(k == n) return 0;
for(int i = 1; i <= n; ++i)
if(c[i]) putchar((a[i] ^ 1) + '0');
else putchar(a[i] + '0');
fflush(stdout);
return 0;
}

浙公网安备 33010602011771号