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]); 
}

 

posted @ 2021-09-07 16:42  TRTTG  阅读(46)  评论(0编辑  收藏  举报