CF1779E Anya's Simultaneous Exhibition 题解
交互题用错误的询问次数故意误导选手太恶劣了。
思路:
这是一种只需要
假设我们已经知道了所有人之间的关系,若
由于任意两点间一定存在一条边,所以可以证明此强连通分量必唯一。
假设这个强连通分量的大小为
于是不难想到用
得到出度
从 corner case 开始考虑:若
我们猜想,当第一次遇到前
为什么?利用反证法证明。(这一段如果只是做题的话没必要看,感性理解即可)
我们认为前
假设实际上是前
至此,命题得证。
代码:
#include <bits/stdc++.h>
#define fuck fflush(stdout);
int n, d[255], e[255];
char s[255];
inline bool cmp(int x, int y){
return d[x] > d[y];
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n - 1; ++i){
for(int j = 1; j <= n; ++j){
if(i == j) s[j] = '0';
else s[j] = '1';
}
printf("? %d %s\n", i, s + 1);
fuck;
scanf("%d", &d[i]);
e[i] = i;
d[n] -= d[i];
}
e[n] = n;
d[n] += (n - 1) * n / 2;
std::sort(e + 1, e + n + 1, cmp);
int ans = n, sum = 0;
for(int i = 1; i <= n - 1; ++i){
for(int j = 1; j <= n; ++j) s[j] = '0';
for(int j = i + 1; j <= n; ++j) s[e[j]] = '1';
printf("? %d %s\n", e[i], s + 1);
fuck;
int x;
scanf("%d", &x);
sum += x;
sum -= (i - 1 - (d[e[i]] - x));
sum += d[e[i]] + 1 - i;
if(sum == i * (n - i)){
ans = i;
break;
}
}
for(int i = 1; i <= n; ++i) s[i] = '0';
for(int i = 1; i <= ans; ++i) s[e[i]] = '1';
printf("! %s\n", s + 1);
fuck;
return 0;
}