题意
这是一道交互题。
有n个人,其中a个是诚实的,另外b=n-a个是不诚实的。每次你可以对x询问y是否诚实,若x是诚实的则会如实回答,否则的话就会按照某种策略随意回答。
问能否通过不超过2n次询问确定每个人是否诚实
分析
首先若
则无解,因为我们可以选出
个不诚实的人去假扮诚实的人。
很显然的思路就是要去找到一个诚实的人,然后扫一遍就可以得到答案了。
那么我们可以考虑构造一条链
,其中第
个人说第
个人是诚实的。
若其中存在某个人是诚实的,那么链最末端那个人就一定是诚实的。
考虑维护一个栈,当栈顶元素说另外一个人是不诚实时,这两个人一定至少有一人是不诚实的,那么就把它们抵消掉。
因为
,所以到后面一定可以得到一个诚实的人,然后就做完了。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
const int N=10005;
int a,b,n,stack[N],ans[N];
int main()
{
scanf("%d%d",&a,&b);
if (a<=b) {printf("Impossible");return 0;}
n=a+b;
int top=0,re;
for (int i=1;i<n;i++)
{
if (!top) {stack[++top]=i;continue;}
printf("? %d %d\n",stack[top],i);
fflush(stdout);
char op[2];scanf("%s",op);
if (op[0]=='N') top--;
else stack[++top]=i;
}
re=stack[top];
for (int i=0;i<n;i++)
{
printf("? %d %d\n",re,i);
fflush(stdout);
char op[2];scanf("%s",op);
if (op[0]=='N') ans[i]=0;
else ans[i]=1;
}
printf("! ");
for (int i=0;i<n;i++) putchar(ans[i]+'0');
puts("");
return 0;
}