(交互题)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;
}

猜你喜欢

转载自blog.csdn.net/qq_39953680/article/details/84438442