1. 程式人生 > >EOJ Monthly 2018.11 猜價格 (模擬)

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;
}