Codeforces Round #534 (Div. 2)D. Game with modulo(交互题)(思维+二分)

D. Game with modulo

题意:

求一个数字 a ( 1 − 1 e 9 ) a(1-1e9) a(11e9),最多询问60次。
每次询问输入 x , y x,y x,y
( x m o d    a ) ≥ ( y m o d    a ) (x \mod a)\ge (y \mod a) (xmoda)(ymoda) 输出 x x x否则输出 y y y

题解:

首先分析一下若 a a a ( x , 2 x ] (x,2x] (x,2x]区间内,询问 ? x ? x ?x 2 x 2x 2x返回必为 x x x;
因此可以依次询问 ( 0 , 1 ) , ( 1 , 2 ) , ( 2 , 4 ) , … , ( 2 29 , 2 30 ) (0,1),(1,2),(2,4),\dots,(2^{29},2^{30}) (0,1),(1,2),(2,4),,(229,230), a a a所在的区间必为第一个返回 x x x的区间;
区间找到之后,在 ( x , 2 x ] (x,2x] (x,2x]内二分就好,(感觉自己二分不太熟练,经常出错,有待加强。)

代码:

#include<bits/stdc++.h>
using namespace std;
string s;
int base[39];
char query(int x,int y){
    cout<<"?"<<" "<<x<<" "<<y<<endl;
    fflush(stdout);
    char c;
    cin>>c;
    return c;
}
int half(int l,int r){
    int mid,ans,ll=l,rr=r;
    if(query(0,l)=='x')return l;
  /*  while(ll<=rr){                        //写法一,比较笨,调了好多次
        mid=(ll+rr+1)>>1;
        if(mid==l)break;
        if(query(l,mid)=='x')ans=mid,rr=mid-1;
        else ll=mid+1;
    }
    return ans;
*/
    while(l+1<r){                            //写法二,借鉴来的
        mid=(l+r)>>1;
        if(query(l,mid)=='y')l=mid;
        else r=mid;
    }
    return l+1;
}
void solve(){
    vector<int>ans;ans.clear();
    for(int i=0;i<30;i++)if(query(base[i],base[i+1])=='x'){ans.push_back(i);break;}
    for(int i=0;i<1;i++){
      int as=half(base[ans[i]],base[ans[i]+1]);
      cout<<"! "<<as<<endl;
    }
   // fflush(stdout);
}
int main(){
 //   freopen("tt.in","r",stdin),freopen("tt.out","w",stdout);
    base[0]=1;
    for(int i=1;i<=30;i++)base[i]=base[i-1]*2;
    while(cin>>s){
        if(s=="start")solve();
        else return 0;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值