CF1556 D. Take a Guess
https://codeforces.com/problemset/problem/1556/D
题意:
交互题,有一个隐藏的n个数的序列,你可以进行不超过2*n次询问
询问方式为每次问某两个位置的按位与结果 或者是 按位或结果
最后回答序列第k小的数是谁
利用 (a&b) + (a|b) = a+b
先用6次询问查出前三个数两两相加的和,可以解出这三个数
然后后面就可以用2次询问得出一个已知和一个未知数的和,从而求出未知数
#include<bits/stdc++.h> using namespace std; #define N 10002 int s[N]; void solve(int a,int b,int c) { int x,x1,x2,x3; printf("and %d %d\n",a,b); fflush(stdout); scanf("%d",&x1); printf("or %d %d\n",a,b); fflush(stdout); scanf("%d",&x); x1+=x; printf("and %d %d\n",b,c); fflush(stdout); scanf("%d",&x2); printf("or %d %d\n",b,c); fflush(stdout); scanf("%d",&x); x2+=x; printf("and %d %d\n",a,c); fflush(stdout); scanf("%d",&x3); printf("or %d %d\n",a,c); fflush(stdout); scanf("%d",&x); x3+=x; x=1ll*x1+x2+x3>>1; s[a]=x-x2; s[b]=x-x3; s[c]=x-x1; // printf("%d %d %d\n",s[a],s[b],s[c]); } void solve2(int a,int b) { int x1,x; printf("and %d %d\n",a,b); fflush(stdout); scanf("%d",&x1); printf("or %d %d\n",a,b); fflush(stdout); scanf("%d",&x); x1+=x; s[b]=x1-s[a]; } int main() { int n,k; scanf("%d%d",&n,&k); solve(1,2,3); for(int i=4;i<=n;++i) solve2(i-1,i); sort(s+1,s+n+1); printf("finish %d",s[k]); }