ARC070F HonestOrUnkind
Link
如果\(b\ge a\),那么一定无解。
\(a\)个Unkind的人装成Honest,指认真正的Honest为Unkind,指认这\(a\)个装成Honest的人为Honest,指认其它Unkind的人为Unkind。这样就无法分辨真正的Honest为哪\(a\)个。
如果我们可以确定一个人是Honest,那么就可以判断出所有人的Kind了。
考虑维护一个栈,先把第一个人加入栈,然后往后扫。
每扫到一个人,就像栈顶的人询问扫到的人的Kind,如果是Honest就将这个人入栈,否则这两个人中一定有至少一个是Unkind,我们将栈顶的人弹出。
最后栈中会剩下一些元素,其中一定存在至少一个Honest的人。
不难发现如果栈中存在Unkind的人,那么Unkind的人一定在栈底,因此栈顶的人一定是Honest。
#include<stack>
#include<cstdio>
std::stack<int>stk;char str[5007],ans[2];
int ask(int a,int b){return printf("? %d %d\n",a-1,b-1),fflush(stdout),scanf("%s",ans),ans[0]=='Y';}
int main()
{
int n,a,b;scanf("%d%d",&a,&b),n=a+b;
if(a<=b) return puts("Impossible"),0;
for(int i=1;i<=n;++i) stk.empty()||ask(stk.top(),i)? stk.push(i):stk.pop();
for(int i=1;i<=n;++i) str[i]=ask(stk.top(),i)+'0';
printf("! %s",str+1);
}