EOJ Monthly 2018.11 猜价格 (模拟)

分三种情况:
1.k=1。此时每次都说反话,反着二分即可。

2.1<k <= n。那么在前n次问答中一定会出现一次错误,通过不断输出1找出那个错误发生的位置(若回答是>那这就是错误)。此后每隔k次就会有一个错误发生,判断出来即可。

3.k > n。不能用上面的方式,否则回答次数会超过2n。因为k>n,所以在2n次问答中只会出现一个错误,所以通过每次输出两个同样的数,判断是否出现错误。当两次得到应答不一致时,就说明错误发生,再输出一个同样的数确定是非。此外便可以正常二分。

*清空缓冲区要用cin

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
typedef long long LL;
LL n,k;

void gao1()
{
    LL mid,L= 1, R= ((1LL)<<n)-1;
    char c;
    while(L<=R){
        mid = L+(R-L)/2;
        printf("%lld\n",mid);
        cin>>c;
        if(c== '=' ){
            break;
        }
        else if(c== '<' ){
            R = mid-1;
        }
        else{
            L = mid+1;
        }
    }
}

void gao2()
{
    int pos;
    char c;
    for(int i=1;i<=n;++i){
        printf("1\n");
        cin>>c;
        if(c=='>'){
            break;
        }
    }
    LL mid,L= 1, R= ((1LL)<<n)-1;
    int cnt = 1;
    while(L<=R){
        mid = L+(R-L)/2;
        printf("%lld\n",mid);
        cin>>c;
        if(c=='=')
            break;
        else if(c=='<'){
            if(cnt==k){
                cnt = 0;
                R = mid-1;
            }
            else  L = mid+1;
        }
        else{
            if(cnt==k){
                cnt = 0;
                L = mid+1;
            }
            else{
                R = mid-1;
            }
        }
        cnt++;
    }
}

void gao3()
{
    LL mid,L= 1, R= ((1LL)<<n)-1;
    char c1,c2;
    bool flag = true;
    while(L <= R ){
        mid = L+(R-L)/2;
        printf("%lld\n",mid);
        cin>>c1;
        if(c1=='=')
            break;

        if(flag){
            printf("%lld\n",mid);
            cin>>c2;
            if(c2=='=')
                break;
            if(c1!=c2){                 //error
                flag = false;
                char c3;
                printf("%lld\n",mid);
                cin>>c3;
                if(c1==c3){
                    if(c1=='<') L = mid+1;
                    else R  = mid-1;
                }
                else{
                    if(c2=='<') L = mid+1;
                    else R = mid-1;
                }
            }
            else{
                if(c1=='<') L = mid+1;
                else R  = mid-1;
            }
        }
        else{
            if(c1=='<') L = mid + 1;
            else R  = mid - 1;
        }
    }
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    #endif
    int in;
    scanf("%lld %lld",&n, &k);
    if(n==1){
        printf("1\n");
        return 0;
    }

    if(k==1)  gao1();
    else if(k<=n)  gao2();
    else  gao3();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xiuwenli/p/9975501.html