cf1088D Ehab and another another xor problem (构造)

题意:有两数a,b,每次你可以给定c,d询问a xor c和b xor d的大小关系,最多询问62次($a,b<=2^{30}$),问a和b

考虑从高位往低位做,正在做第i位,已经知道了a和b的前i-1位

这样的话,只要让a、c,b、d的前i-1位相同,就和前i-1位没关系了

考虑在第i位上abcd的情况对应的回答(后面的位数都给0),其中~表示与第i位后面的相关

那我可以分别用01 10询问两次,如果是先大后小或是先小后大,就能判断出是00或者11

但如果前后两次相同,那就有可能是01或者10

考虑上一次两次相同的时候是在第j位,具体到底是大于还是小于

然后又因为j+1~i-1位它们a和b都是相同的,所以这个大于还是小于就取决于第i位,所以能得出是01还是10

如果这是第一次相同,那直接再拿00询问一次就可以得到答案

一共61次

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 #define MP make_pair
 5 using namespace std;
 6 typedef long long ll;
 7 const int maxn=1;
 8 
 9 inline char gc(){
10     return getchar();
11     static const int maxs=1<<16;static char buf[maxs],*p1=buf,*p2=buf;
12     return p1==p2&&(p2=(p1=buf)+fread(buf,1,maxs,stdin),p1==p2)?EOF:*p1++;
13 }
14 inline ll rd(){
15     ll x=0;char c=gc();bool neg=0;
16     while(c<'0'||c>'9'){if(c=='-') neg=1;c=gc();}
17     while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=gc();
18     return neg?(~x+1):x;
19 }
20 
21 inline int get(int c,int d){
22     printf("? %d %d\n",c,d);
23     fflush(stdout);
24     return rd();
25 }
26 
27 int main(){
28     //freopen("","r",stdin);
29     int i;
30     int cp=0,dp=0;
31     int a=0,b=0;
32     int lst=0;
33     for(i=29;i>=0;i--){
34         int v1=get(cp,dp|(1<<i)),v2=get(cp|(1<<i),dp);
35         if(v1==v2){
36             if(lst==1) a|=(1<<i);
37             else if(lst==-1) b|=(1<<i);
38             else{
39                 if(get(cp,dp)==1) a|=(1<<i);
40                 else b|=(1<<i);
41             }
42             lst=v1;
43         }else if(v1==1) a|=(1<<i),b|=(1<<i);
44         cp=a,dp=b;
45     }
46     printf("! %d %d\n",a,b);
47     fflush(stdout);
48     return 0;
49     
50 }

 

posted @ 2018-12-08 20:55  Ressed  阅读(298)  评论(0编辑  收藏  举报