CF Div 2 D. Game with modulo(交互+二分)

D. Game with modulo

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

This is an interactive problem.

Vasya and Petya are going to play the following game: Petya has some positive integer number aa. After that Vasya should guess this number using the following questions. He can say a pair of non-negative integer numbers (x,y)(x,y). Petya will answer him:

  • "x", if (xmoda)≥(ymoda)(xmoda)≥(ymoda).
  • "y", if (xmoda)<(ymoda)(xmoda)<(ymoda).

We define (xmoda)(xmoda) as a remainder of division xx by aa.

Vasya should guess the number aa using no more, than 60 questions.

It's guaranteed that Petya has a number, that satisfies the inequality 1≤a≤1091≤a≤109.

Help Vasya playing this game and write a program, that will guess the number aa.

Interaction

Your program should play several games.

Before the start of any game your program should read the string:

  • "start" (without quotes) — the start of the new game.
  • "mistake" (without quotes) — in the previous game, you found the wrong answer. Your program should terminate after reading this string and it will get verdict "Wrong answer".
  • "end" (without quotes) — all games finished. Your program should terminate after reading this string.

After reading the string "start" (without quotes) the new game starts.

At the beginning, your program should ask several questions about pairs of non-negative integer numbers (x,y)(x,y). You can only ask the numbers, that satisfy the inequalities 0≤x,y≤2⋅1090≤x,y≤2⋅109. To ask a question print "? x y" (without quotes). As the answer, you should read one symbol:

  • "x" (without quotes), if (xmoda)≥(ymoda)(xmoda)≥(ymoda).
  • "y" (without quotes), if (xmoda)<(ymoda)(xmoda)<(ymoda).
  • "e" (without quotes) — you asked more than 6060 questions. Your program should terminate after reading this string and it will get verdict "Wrong answer".

After your program asked several questions your program should print the answer in form "! a" (without quotes). You should print the number aa satisfying the inequalities 1≤a≤1091≤a≤109. It's guaranteed that Petya's number aa satisfied this condition. After that, the current game will finish.

We recall that your program can't ask more than 6060 questions during one game.

If your program doesn't terminate after reading "mistake" (without quotes), "end" (without quotes) or "e" (without quotes), it can get any verdict, because it will continue reading from closed input. Also, if your program prints answer or question in the incorrect format it can get any verdict, too. Be careful.

Don't forget to flush the output after printing questions and answers.

To flush the output, you can use:

  • fflush(stdout) in C++.
  • System.out.flush() in Java.
  • stdout.flush() in Python.
  • flush(output) in Pascal.
  • See the documentation for other languages.

It's guaranteed that you should play at least 11 and no more than 100100 games.

Hacks:

In hacks, you can use only one game. To hack a solution with Petya's number aa (1≤a≤1091≤a≤109) in the first line you should write a single number 11 and in the second line you should write a single number aa.

Example

input

Copy

start
x
x
start
x
x
y
start
x
x
y
y
end

output

Copy

? 0 0
? 10 1
! 1
? 0 0
? 3 4
? 2 5
! 2
? 2 4
? 2 5
? 3 10
? 9 1
! 3

Note

In the first test, you should play 33 games with Petya's numbers 11, 22 and 33.

In the first game, Petya will answer "x" (without quotes) to any question, because (xmod1)=0(xmod1)=0 for any integer xx.

In the second game, if you will ask pair (0,0)(0,0), the answer will be "x" (without quotes), because (0mod2)≥(0mod2)(0mod2)≥(0mod2). But if you will ask pair (2,5)(2,5), the answer will be "y" (without quotes), because (2mod2)<(5mod2)(2mod2)<(5mod2), because (2mod2)=0(2mod2)=0 and (5mod2)=1(5mod2)=1.

題意:開始時有一個a,每次你可以詢問一個x和y,根據你的詢問他可以給你 x%a 和 y%a 的大小關係,是否能在不超過60次問詢的前提下找到a的值 1=<a<=1e9

題解:交互題!!!首先就是要注意在每次printf之後要加上fflush語句,不然未知錯誤無數遍,這道題的思路就是枚舉2的冪次,枚舉的x=2^i , y=2^(i+1) 當 a>y 時 y%a > x%a 而當 x<a<=y時 y-a<x 則若出現x%a>=y%a a一定在x,y之間 ,那麼先找到轉折點然後再二分即可,但是這道題二分有一點奇怪,用了另一種寫法就AC了,以前的二分模板不適用....

#include<bits/stdc++.h>
using namespace std;
#define Sheryang main
const int maxn=1e6+7;
typedef long long ll;
const int mod=1e9+7;
int read(){int c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
#define read read()
/* keep hungry and keep calm! */

char s[10];
int Sheryang()
{
    scanf("%s",s);
    while(strcmp(s,"start")==0){
        int x=1,y=2;
        char f[5];

        printf("? 0 1\n");
        fflush(stdout);
        scanf("%s",f);
        if(f[0]=='x'){
            printf("! 1\n");
            fflush(stdout);
            scanf("%s",s);
            continue;
        }
        while(1){

            printf("? %d %d\n",x,y);
            fflush(stdout);
            scanf("%s",f);

            if(f[0]=='y'){
                x=x*2;
                y=y*2;
            }else{
                int l=x,r=y;
                while(r-l>1){
                    int mid=(l+r)/2;

                    printf("? %d %d\n",l,mid);
                    fflush(stdout);
                    scanf("%s",f);

                    if(f[0]=='x'){
                        r=mid;
                    }else{
                        l=mid;
                    }
                }
                printf("! %d\n",r);
                fflush(stdout);
                break;
            }
        }
        scanf("%s",s);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章