CF1556D-Take a Guess【交互】

1|0正题

题目链接:https://codeforces.com/contest/1556/problem/D


1|1题目大意

现在有n个你不知道的数字,你有两种询问操作

  1. 询问两个下标的数字的and
  2. 询问两个下标的数字的or

要求在2n次操作以内求出第k小的数字

1n104,0ai109


1|2解题思路

显示我们取and之后为0or之后为1的位就可以得到两个数字的异或,所以我们可以通过2n2次询问得到所有数字之间的异或值,那么此时我们就只需要知道一个数字就可以得到其他所有的。

然后考虑怎么求某一个数字,我们前面的步骤中拿1orand其他所有的值,不难发现每次我们除了知道异或值还能确定这两个数字异或之后为0的位上的具体值。

那么我们不知道位的肯定是1和其他所有数字都不同的,也就是这些位上除了1其他数字都相同,那么我们直接拿另外两个数and/or一下再取这些位上的值就好了。

这样询问次数就是2n1次,可以通过本题。


1|3code

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e4+10; int n,k,a[N],p[N]; int main() { scanf("%d%d",&n,&k); int MS=(1<<30)-1,ans=0,bns=0; for(int i=2,x,y;i<=n;i++){ printf("and 1 %d\n",i); fflush(stdout); scanf("%d",&x); printf("or 1 %d\n",i); fflush(stdout); scanf("%d",&y);y^=MS; p[i]=(MS^(x|y)); ans|=x;bns|=y; } int c=MS^(ans|bns),cns; printf("and 2 3\n"); fflush(stdout); scanf("%d",&cns);cns&=c; a[1]=(c^cns)|ans; for(int i=2;i<=n;i++)a[i]=a[1]^p[i]; sort(a+1,a+1+n); printf("finish %d\n",a[k]); fflush(stdout); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/15205582.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(49)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示