(互動題)EOJ Monthly 2018.11 D. 猜價格
阿新 • • 發佈:2018-11-24
容易想到不斷ask(1),如果得到'>',那麼該次詢問必定為假,那麼接下來k次一個週期,第k次必為假;同時運用二分法詢問,在n次以內能夠得出答案。
但是如果n<k,則詢問次數有可能大於2n;這時候可以在每次二分詢問中詢問兩次,如果答案不一,那麼詢問第三次(此次必為真),然後接下來k-3或k-2次以內能得到系統正確作答,而此時最多需要n-1次詢問就能得出結果,而且n<k,那麼可以保證接下來都是真話,不斷二分即可。
如果考慮極端情況:n=k-1、兩次詢問第一次為假、要詢問n次,因為最後一次為‘=’,系統不會說假話,對結果沒有影響
注意:不要用r=(1<<n)-1,這裡1會預設為int型別
#include <bits/stdc++.h> #define For(i,x,y) for(int i=(x);i<=(y);++i) #define Fov(i,x,y) for(int i=(x);i>=(y);--i) #define Fo(i,x,y) for(int i=(x);i<(y);++i) #define midf(a,b) ((a)+(b)>>1) #define L(_) (_)<<1 #define R(_) ((_)<<1)|1 #define fi first #define se second #define ss(_) scanf("%s",_) #define si(_) scanf("%d",&_) #define sii(x,y) scanf("%d%d",&x,&y) #define siii(x,y,z) scanf("%d%d%d",&x,&y,&z) #define sl(_) scanf("%lld",&_) #define mem(x,y) memset(x,y,sizeof(x)) using namespace std; typedef long long ll; typedef pair<int,int>P; inline int read() { char ch=getchar(); int x=0, f=1; while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar();} while('0'<=ch&&ch<='9') { x=x*10+ch-'0'; ch=getchar();} return x*f; } const int inf=0x3f3f3f3f; const double pi=acos(-1.0); char a; char ask(ll x) { cout<<x<<endl; fflush(stdout); cin>>a; if(a=='=') exit(0); return a; } int main() { //freopen("in.txt","r",stdin); int n,k; sii(n,k); char res,x,y; ll l=1,r=(l<<n)-1,mid; int cnt=0; if(k<=n) { while(ask(1)=='<'){} while(l<=r) { mid=(l+r)>>1; x=ask(mid); ++cnt; if(x=='<') { if(cnt==k) r=mid-1,cnt=0; else l=mid+1; } else { if(cnt==k) l=mid+1,cnt=0; else r=mid-1; } } } else { while(l<=r) { mid=(l+r)>>1; x=ask(mid); y=ask(mid); if(x!=y) { while(l<=r) { res=ask(mid); if(res=='<') l=mid+1; else r=mid-1; mid=(l+r)>>1; } } if(x=='<') l=mid+1; else r=mid-1; } } return 0; }