codeforces1011D Rocket(交互题)

题目链接:

CF-1011D

题目大意:

常见交互题套路,有一个数字要猜,假设为 x x ;给计算机的数假设为 y y ,会得到以下三种回答:

  • x<y x < y ,回答 1 − 1
  • x==y x == y ,回答 0 0
  • x>y x > y ,回答 1 1

但是,现在计算机坏了,对于某些询问会“说谎”;所谓“说谎”就是该回答 1 − 1 的回答了 1 1 ;反之,该回答 1 1 的回答了 1 − 1
抽象为 01 01 字符串, 0101 0101 表示第 1 1 3 3 次询问计算机会“说谎”;若询问的次数大于了 4 4 ,就会循环;即第 5 5 7 7 次会“说谎”。
现在,给这个 01 01 串的长度 n n ,以及 x x 的最大范围 m m (即 xm x ≤ m )。
还要求询问次数最多不超过 60 60 次。

数据范围:

1m1091n30 1 ≤ m ≤ 10 9 1 ≤ n ≤ 30

解题思路:

一开始完全没有思路,那个 01 01 串都没有给,猜上加猜?怎么猜?!
后来仔细一想,如果那个 01 01 串确定了,就是一个很简单的交互题了,直接二分就完了。
难点就在怎么确定那个 01 01 串?

其实,拿 1 1 去问个 n n 次就可以确定那个 01 01 串了;
如果回答为 0 0 ,那 x x 就是 1 1 ,这个就先不考虑了;
除此之外,对于每个询问,都应该满足 1<x 1 < x ,回答都应该是 1 1 ;如果不是,那这次就是在“说谎”;
这样恢复出那个 01 01 串后,这道题就解决了。

AC代码:
/**********************************************
 *Author*        :XzzF
 *Created Time*  : 2018/7/27 23:52:41
 *Ended  Time*  : 2018/7/27 23:59:18
*********************************************/

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
const int inf = 1 << 30;
const LL INF = 1LL << 60;

int n, m;
bool lie[50];  //lie[i]为true表示第i次会说谎

int Recover(int y) {
    printf("%d\n", y);
    fflush(stdout);
    int num;
    scanf("%d", &num);
    if(num == 0 || num == -2) exit(0);
    return num;
}

bool check(int y, int cnt) {
    printf("%d\n", y);
    fflush(stdout);
    int num;
    scanf("%d", &num);
    if(num == 0 || num == -2) exit(0);
    if(num == 1) {  //y < expect
        if(lie[cnt]) return true;
        else return false;
    }
    else if(num == -1) {   //y > expect
        if(lie[cnt]) return false;
        else return true;
    }
}

int main()
{
    scanf("%d %d", &m, &n);
    memset(lie, false, sizeof(lie));
    for(int i = 0; i < n; i++) {
        int val = Recover(1);
        if(val == -1) lie[i] = true;
    }
    int l = 1, r = m;
    int cnt = 0;
    while(l <= r) {
        int mid = (l + r) >> 1;
        if(check(mid, cnt % n)) r = mid - 1;  //忘了mod,WA了几发
        else l = mid + 1;
        cnt++;
    }
    return 0;
}

你可能感兴趣的:(Codeforces)