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);
}
posted @ 2020-04-08 23:03  Shiina_Mashiro  阅读(141)  评论(0编辑  收藏  举报