考虑当$a\le b$时,构造两种方案,满足诚实的人不交,接下来要求对于任意询问,这两种方案的答案都有可能相同

考虑询问$(i,j)$,若$i$在两种方案中有一种不诚实,那么总可以让答案相同,又因为诚实的人不交,因此一定可行

当$a>b$,我们只需要找到一个诚实的人就可以做了,考虑如何找到这个诚实的人:

对于询问$(i,j)$,若结果为不诚实,至少存在一个人不诚实,考虑同时删去$i$和$j$,显然最终不可能只剩下不诚实的人

维护一个栈(初始为空),从1到$n$遍历所有人,并询问$(栈顶,i)$,考虑结果:

1.结果为不诚实,同时删去(弹出)栈顶和$i$即可

2.结果为诚实,将$i$加入栈中,并继续此过程

当我们询问完之后,可以发现栈中若栈顶不诚实,由于栈顶的下一个元素认为栈顶诚实,因此其也不诚实,以此类推,整个栈中所有人都不诚实,即矛盾

通过栈顶再$n$次询问即可确定剩余的人

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 4005
4 stack<int>st;
5 int a,b,ans[N];
6 char s[11];
7 int query(int x,int y){
8 printf("? %d %d\n",x-1,y-1);
9 fflush(stdout);
10 scanf("%s",s);
11 return s[0]=='Y';
12 }
13 int main(){
14 scanf("%d%d",&a,&b);
15 if (a<=b){
16 printf("Impossible");
17 return 0;
18 }
19 for(int i=1;i<=a+b;i++)
20 if (st.empty())st.push(i);
21 else{
22 if (query(st.top(),i))st.push(i);
23 else st.pop();
24 }
25 for(int i=1;i<=a+b;i++)ans[i]=query(st.top(),i);
26 printf("! ");
27 for(int i=1;i<=a+b;i++)printf("%d",ans[i]);
28 }

最新文章

  1. 【HTML】字符(Glyphs)收集
  2. Android 进阶 Android 中的 IOC 框架 【ViewInject】 (下)
  3. java.util.logging.Logger 使用详解
  4. linux信号处理时机
  5. table奇偶行设置颜色代码
  6. SQL Server转发记录指针的坏味道
  7. Linux-LNMP LAMP LNMPA
  8. photoshop:把路径存储为形状
  9. iOS NavigaitonController详解(code版)
  10. JobTracker等相关功能模块初始化
  11. PHP之CI框架第一课
  12. Centos 7.3 安装配置 PostgreSQL 9.x
  13. Android Studio教程09-加载器Loader的使用
  14. vue教学视频(小程序教学视频)
  15. 深入理解Java虚拟机05--虚拟机类加载机制
  16. TCP/IP协议 模型
  17. Python-random 随机数模块
  18. 转:winform 打包自动安装数据库
  19. 压缩归档文件审查工具p7zip-full
  20. 迁移TFS,批量将文档导入SharePoint 2013 文档库

热门文章

  1. 面试官问我MySQL调优,我真的是
  2. golang引用第三方包的报错:no required module provides package [完美解决]
  3. Tracking Analyst Tools(Tracking Analyst 工具)
  4. Visual Studio CMake 项目和 WSL
  5. Postman实现SHA256withRSA签名
  6. 1.2 Simple Code!(翻译)
  7. Tekton+Argocd实现自动化流水线
  8. JVM:内存模型
  9. [no code][scrum meeting] Beta 10
  10. 零基础入门之Linux进程基础