Codeforces Round #525 (Div. 2) D - Ehab and another another xor problem(互動題之猜數)
題意
互動題,要猜a和b,你輸入c和d,
記e=a異或c,f=b異或d
e>f返回1,e==f返回0,e<f返回-1
給你最多62次機會,要求猜出a和b
思路來源
https://blog.csdn.net/weixin_43790474/article/details/84815383
傅老師%%%
題解
(c,d)代表讀入了(? c d)
詢問(now1,now2),初始now1=0,now2=0;
將結果讀入op,op維護從第i位起兩數的大小關係
一、op=0,說明自第i位起,後續都相同
那麼每次只需區分00還是11即可,
詢問(now1^(1<<i),now2),左大則為00,右大則為11
二、op≠0,只能為00,01,10,11中的一種(第i位的a與第i位的b)
將第i位同時取反,即詢問(now1^(1<<i),now2^(1<<i)),記為op1
(1)op=1,不可能為01
①op1=1,不可能為10,只能為00,11
詢問(now1^(1<<i),now2),為1則為00,為-1則為11
②op1=1,只能為10,此時去掉這一位,大小關係可能反轉,
故令now1,now2更新後,再詢問op
(2)op=-1,不可能為10
①op1=-1,不可能為01,只能為00,11
詢問(now1^(1<<i),now2),為1則為00,為-1則為11
②op1=1,只能為01,此時去掉這一位,大小關係可能反轉,
故令now1,now2更新後,再詢問op
由於初始會詢問一次op確定大小關係,
30位每一位最多詢問兩次,最後!輸出,恰62次。
心得
互動題特點:每次輸出完之後及時fflush(stdout),printf與scanf互換
這題半夜做出來可能性還是不大的,好好補就是了
互動題其實挺有意思的,只是被虐的挺慘……
見過三四道了……上次華師大那個就沒補GG
一早起來發現C被n==1情況hack掉了心情複雜
程式碼
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <map> #include <vector> #include <stack> #include <queue> #include <functional> const int INF=0x3f3f3f3f; const int maxn=2e4+10; const int mod=1e9+7; const int MOD=998244353; const double eps=1e-7; typedef long long ll; #define vi vector<int> #define si set<int> #define pii pair<int,int> #define pi acos(-1.0) #define pb push_back #define mp make_pair #define lowbit(x) (x&(-x)) #define sci(x) scanf("%d",&(x)) #define scll(x) scanf("%lld",&(x)) #define sclf(x) scanf("%lf",&(x)) #define pri(x) printf("%d",(x)) #define rep(i,j,k) for(int i=j;i<=k;++i) #define per(i,j,k) for(int i=j;i>=k;--i) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; int a[50],b[50],op,now1,now2; void check(int pos) { int tmp=1<<pos,op1,op2; if(op==0) { printf("? %d %d\n",now1^tmp,now2);//判斷00 11 fflush(stdout); scanf("%d",&op1); if(op1==1)a[pos]=b[pos]=0; else a[pos]=b[pos]=1; now1^=(a[pos]<<pos);now2^=(b[pos]<<pos); return; } printf("? %d %d\n",now1^tmp,now2^tmp);//00 01 10 11 fflush(stdout); scanf("%d",&op1); if(op==1)//不可能是01 { if(op1==1)//不可能是10 { printf("? %d %d\n",now1^tmp,now2);//00 11 fflush(stdout); scanf("%d",&op2); if(op2==-1)a[pos]=b[pos]=1; else a[pos]=b[pos]=0; now1^=(a[pos]<<pos);now2^=(b[pos]<<pos); } else//本大於,因最高位而翻轉 { a[pos]=1,b[pos]=0; now1^=(a[pos]<<pos);now2^=(b[pos]<<pos); printf("? %d %d\n",now1,now2); fflush(stdout); scanf("%d",&op); } } else//不可能是10 { if(op1==-1)//不可能是01 { printf("? %d %d\n",now1^tmp,now2);//00 11 fflush(stdout); scanf("%d",&op2); if(op2==1)a[pos]=b[pos]=0; else a[pos]=b[pos]=1; now1^=(a[pos]<<pos);now2^=(b[pos]<<pos); } else { a[pos]=0,b[pos]=1; now1^=(a[pos]<<pos);now2^=(b[pos]<<pos); printf("? %d %d\n",now1,now2); fflush(stdout); scanf("%d",&op); } } } int main() { printf("? %d %d\n",now1,now2); fflush(stdout); scanf("%d",&op); for(int i=29;i>=0;--i) { check(i); } printf("! %d %d\n",now1,now2); fflush(stdout); return 0; }