Codeforces Round #534 (Div. 2) D. Game with modulo(取余性质+二分)

本文解析了CodeForces竞赛中的一道交互题D.Gamewithmodulo,详细介绍了如何通过倍增和二分查找策略来猜出初始数a的具体值。文章提供了完整的代码实现,并讨论了特殊情况下a为1或2的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D. Game with modulo

题目链接https://codeforces.com/contest/1104/problem/D

题意:

这题是一个交互题,首先一开始会有一个数a,你最终的目的是要将它猜出来。

每次询问会输出"? x y",然后有:

  • "x" (without quotes), if (a)(a).
  • "y" (without quotes), if (a)<(a).

最多给你60次询问的机会,问最后这个a是多少。

 

题解:

这里会用到取余的性质,假设现在有一个数b,现在有b%a=c。假设a>b那么我们什么都不用管;假设a<=b,我们可以推出c是满足c<a/2的。

也就是说,当x,y都小于a时,必定会输出"y";否则,至少有y<a/2。

那么我们想到一开始令x=1,y=2进行倍增,因为当y=2*x时,若y>a,则有y%a<x%a恒成立,此时也x也是必定小于a的。

那么我们可以通过这个确立一个区间,然后在区间里面进行二分来询问a的值就好了。

注意一下a=1以及a=2时的特殊情况。

 

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mx = 1000000000;
string s;
int query(ll x,ll y){
    printf("? %I64d %I64d\n",x,y);
    fflush(stdout);
    char c;
    getchar();
    scanf("%c",&c);
    if(c=='x'){
        return 0;
    }else return 1;
}
int main(){
    while(cin>>s){
        if(s=="end") break ;
        ll a=1,b=2;
        if(query(a,b)==0){
            if(query(2,1)==0) printf("! 1\n");
            else printf("! 2\n");
            continue ;
        }
        while(query(a,b)){
            a*=2;
            b*=2;
            if(b>=mx){
                b=mx;
                break ;
            }
        }
        ll l=a+1,r=b+1,mid;
        while(l<r){
            mid=l+r>>1;
            if(query(a,mid)) l=mid+1;
            else r=mid;
        }
        printf("! %I64d\n",r);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/heyuhhh/p/10352524.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值