title : 交互题
tags : ACM,交互
date : 2022-2-11
author : Linno


交互题

通俗来讲,交互题与平时题目的输入输出反过来,是让你设计程序去向用户提出询问,由用户给出答案,并且在这基础上由程序推断出正确答案的一种形式。在下面第一道例题中会认识到交互题的基本写法。

应用cf上的话说明怎样调整输入输出:
//This is an interactive problem. Remember to flush your output while communicating with the testing program.** You may use fflush(stdout) in C++, system.out.flush() in Java, stdout.flush() in Python or flush(output) in Pascal to flush the output.

注意事项

  • 每一次输出后都要刷新缓冲区,否则会引起 i d l e n e s s l i m i t e x c e e d e d idleness\ limit\ exceeded idleness limit exceeded错误,在codeforces中是 W r o n g A n s w e r Wrong\ Answer Wrong Answer错误。另外,如果题目含多组数据并且程序可以在未读入所有数据时就知道答案,也仍然要读入所有的数据,否则同样会因为读入混乱引起ILE(可以一次提出多个询问,一次接收所有询问的答案)。同时尽量不要使用快读。

  • 交互题一般会限制查询次数或者查询区间,所以要尽量选择最优的查询方法来得出结果,尽可能做到每次查询都能得到完全不一样的信息,以免浪费机会。

例题

CF1167B Lost Numbers

序列a是4,8,15,16,23,42组成的一个排列。给定4次询问,每次回答出两个位置的数之积,求序列a。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;int a[]={0,4,8,15,16,23,42},d[5];int gcd(int a,int b){return b?gcd(b,a%b):a;
}signed main(){for(int i=1;i<=4;i++){cout<<"? "<<i<<" "<<i+1<<"\n";fflush(stdout);cin>>d[i];}do{if(a[1]*a[2]==d[1]&&a[2]*a[3]==d[2]&&a[3]*a[4]==d[3]&&a[4]*a[5]==d[4]){cout<<"! ";for(int i=1;i<=6;i++) cout<<a[i]<<" ";return 0; }}while(next_permutation(a+1,a+7));return 0;
}
CF843B Interactive LowerBound

给最多2000个询问和50000个递增链表上的结点,给出链头st和x,需要你找到第一个大于等于x的结点。

做法:先用1000次尝试随机地去找比x大且最近的数,然后再用1000次尝试向前找,就能极大概率求出正解。

#include<bits/stdc++.h>
using namespace std;
const int N=50100;
int n,st,x,gl;
int val[N],nex[N];
int main(){srand(time(0)^getpid());cin>>n>>st>>x;gl=st;for(int i=1;i<=1000;i++){int q=1ll*rand()*rand()%n+1;cout<<"? "<<q<<"\n";fflush(stdout);cin>>val[q]>>nex[q];if(val[gl]<val[q]&&val[q]<=x){gl=q;}}for(int i=gl;i!=-1;i=nex[i]){cout<<"? "<<i<<"\n";fflush(stdout);cin>>val[i]>>nex[i];if(val[i]>=x){cout<<"! "<<val[i]<<"\n";fflush(stdout);return 0;}}cout<<"! -1\n";fflush(stdout);
}
CF750F New Year and Finding Roots

给定深度为 h ( h ≤ 7 ) h(h\le 7) h(h≤7)的满二叉树,每次询问可以知道某个节点连向哪几个结点,要求在16次询问内找到根节点。

做法:分析满二叉树的性质:①度为1是叶子节点;②度为2是根节点,直接输出答案;③度为3是普通结点,需要向三个方向bfs访问。

其实只需要讨论第三种情况即可,随机度为3的点st出发,在深度为7的情况下bfs最多需要询问17次找到根节点(可以画图证明),但是我们bfs了10个普通节点和6个叶子结点后(知道其中一个儿子是叶子,那么另外一个就不用搜了),剩下的一个结点就是根节点啦。

#include<bits/stdc++.h>
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;const LL maxn=1<<8;
LL dep[maxn],vis[maxn],c1[maxn],c2[maxn],c3[maxn],c[maxn],s[maxn],up[maxn];
LL h;void Try(LL x,LL from){ //询问 if (vis[x]) return;cout<<"? "<<x<<endl;fflush(stdout);cin>>s[x];vis[x]=1;c[x]=from;cin>>c1[x];if (s[x]>1) cin>>c2[x];if (s[x]>2) cin>>c3[x];
}LL next(LL x,LL from){Try(x,from);if (c1[x]!=c[x]) return c1[x];else if (c2[x]!=c[x]) return c2[x];else return c3[x];
}LL next2(LL x,LL from){Try(x,from);if (c3[x]!=c[x]) return c3[x];else if (c2[x]!=c[x]) return c2[x];else return c1[x];
}LL solve(LL x){ //bfs if (s[x]==2) return x; //碰到度为2的点直接输出答案 if (!dep[x]){LL u1=x,u2=x,u3=x;LL n1=c1[x],n2=c2[x],n3=c3[x];dep[x]=h;while(s[u1]!=1&&s[u2]!=1&&s[u3]!=1){LL l1=u1,l2=u2,l3=u3;u1=n1,u2=n2,u3=n3;n1=next(u1,l1),n2=next(u2,l2),n3=next(u3,l3);if (s[u1]==2) return u1;if (s[u2]==2) return u2;if (s[u3]==2) return u3;dep[x]--;}if (s[x]==1) up[x]=c1[x],Try(up[x],x);else{if (s[u1]!=1) up[x]=c1[x];else if (s[u2]!=1) up[x]=c2[x];else up[x]=c3[x];}dep[up[x]]=dep[x]-1;return solve(up[x]);}if(dep[x]==2){LL u=next(x,c[x]);LL v=next2(x,c[x]);Try(u,x);if (s[u]==2) return u;else return v;}else if(dep[x]==3){LL u=next(x,c[x]); Try(u,x);LL v=next2(x,c[x]); Try(v,x);LL u1=next(u,c[u]),u2=next2(u,c[u]);LL v1=next(v,c[v]),v2=next2(v,c[v]);Try(u1,u),Try(u2,u),Try(v1,v);if (s[u1]==2) return u1;else if (s[u2]==2) return u2;else if (s[v1]==2) return v1;else return v2;}else{LL u=x,lu=c[x],nu;for (LL i=1;i<=h-dep[x];i++){nu=next(u,lu);if (s[u]==2) return u;lu=u,u=nu;}Try(u,lu);if (s[u]==2) return u;else {LL nx;if (s[u]==3) nx=next(x,c[x]);else nx=next2(x,c[x]);Try(nx,x);dep[nx]=dep[x]-1;return solve(nx);}}
}int main(){LL T;cin>>T;while (T--){memset(dep,0,sizeof(dep));memset(vis,0,sizeof(vis));memset(c,0,sizeof(c));memset(c1,0,sizeof(c1));memset(c2,0,sizeof(c2));memset(c3,0,sizeof(c3));memset(s,0,sizeof(s));memset(up,0,sizeof(up));cin>>h;if (h<=4){  //深度小于5可以一个一个问 for (LL i=1;i<=(1<<h)-1;i++{cout<<"? "<<i<<endl;fflush(stdout);LL n;cin>>n;LL x;for (LL j=1;j<=n;j++) cin>>x;if (n==2) {cout<<"! "<<i<<endl;break;}}}else{ //从1号点出发搜索 LL from=1;Try(from,0);cout<<"!"<<" "<<solve(from)<<endl;}}return 0;
}

参考资料

https://oi-wiki.org/contest/interaction/

【算法竞赛学习笔记】交互题入门相关推荐

  1. 【算法竞赛学习笔记】pb_ds-超好懂的数据结构

    title : pb_ds date : 2021-8-21 tags : ACM,数据结构 author : Linno 简介 pb_ds库全称Policy-Based Data Structure ...

  2. 【算法竞赛学习笔记】快速傅里叶变换FFT-数学提高计划

    tilte : 快速傅里叶变换FFT学习笔记 tags : ACM,数论 date : 2021-7-18 简介 FFT(Fast Fourier Transformation),中文名快速傅里叶变换 ...

  3. 【算法竞赛学习笔记】状压DP

    title : 状压DP date : 2022-3-5 tags : ACM,图论,动态规划 author : Linno 状压DP 状态压缩,是利用二进制数的性质对问题进行优化的一种算法,经常与搜 ...

  4. 【算法竞赛学习笔记】KD-Tree

    title : KD-Tree date : 2022-4-7 tags : ACM,数据结构 author : Linno K-D tree K-D树是在k维欧几里得空间中组织点的数据结构.在算法竞 ...

  5. 【算法竞赛学习笔记】莫队算法-超优雅的暴力算法

    title : 莫队算法 tags : ACM,暴力 date : 2021-10-30 author : Linno 普通莫队 常用操作:分块/排序/卡常/离散化等,直接上板子. luoguP270 ...

  6. 【算法竞赛学习笔记】Link-Cut-Tree基础-超好懂的数据结构

    titile : Link-Cut-Tree time : 2021-7-21 tags : ACM,数据结构 author : Linno LCT Link-Cut-Tree,中文名为动态树,是一种 ...

  7. 【算法竞赛学习笔记】离散对数与BSGS-数学提升计划

    title : 离散对数与BSGS date : 2021-8-12 tags : ACM,数论 author Linno 阶 对与m互质的整数a,我们记满足an≡1modma^n\equiv 1\m ...

  8. 【算法竞赛学习笔记】超好懂的斯坦纳树详解!!!

    title : 斯坦纳树 tags : ACM 图论 date : 2021-6-26 author : Linno 什么是斯坦纳树 给定 n 个点 A1,A2,⋯,An试求连接此n个点,总长最短的直 ...

  9. 【算法竞赛学习笔记】佩尔方程-数学提升计划

    title : 佩尔方程 date : 2021-10-31 tags : ACM,数学 author : Linno 佩尔方程 形如x2−dy2=1(d>1且d不为完全平方数)x^2-dy^2 ...

最新文章

  1. 网页(Webpage)粒度分析算法
  2. Java 编程的动态性 第1 部分: 类和类装入--转载
  3. Spring cloud(Finchley)微服务框架,sleuth整合zipkin链路追踪失效的问题
  4. mysql允许远程访问
  5. Flask部署| gunicorn、nginx部署flask项目,并用supervisor来管理进程
  6. 文件无刷新上传(swfUpload与uploadify)
  7. HDU 1222 Wolf and Rabbit
  8. 滴滴等8家网约车平台将增设“一键叫车”功能 便利老年人打车
  9. webstorm破解方法
  10. 华为P40手机点位图PCBDOC下载
  11. Premiere Pro之视频转场效果(四)
  12. 手工定制眼镜将风靡中国(lyy bros)
  13. 室内定位:基于NB/LTE Cat.1蜂窝网络的穿戴设备定位 BLE-4
  14. Vue速成day01
  15. 在当前项目组中引入敏捷开发思想
  16. Cousera-Introduction to Data Science in Python Assignment1-4答案
  17. 为什么工程师出身的 CEO 越来越“香”?
  18. Streambox Ripper的问题
  19. 海洋cms泛目录系统
  20. Windows下msysGit安装

热门文章

  1. dotnet安装包时找不到依赖关系_NET Framework 版本和依赖关系
  2. c语言模块化编程extern的用法,关于模块化编程extern用法
  3. springboot入门系列教程|第九篇:springboot实现图片上传与显示(附源码)
  4. schedule_delayed_work 用法详解
  5. 坑爹fastjson又成黑洞!这次危害可导致服务瘫痪!
  6. 硬盘分区工具EASEUS Partition Master Home Edition 8.0.1
  7. 当HTC SYNC(91助手)连接不上手机时,怎么办?
  8. UE4动态修改材质参数
  9. 不装了、摊牌了,我们要搞事情
  10. MySQL项目-淘宝用户购物行为数据可视化分析