1. 程式人生 > >(互動題)EOJ Monthly 2018.11 D. 猜價格

(互動題)EOJ Monthly 2018.11 D. 猜價格

EOJ Monthly 2018.11 D. 猜價格

容易想到不斷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;
}