其他分享
首页 > 其他分享> > CF1103B Game with modulo

CF1103B Game with modulo

作者:互联网

一、题目

点此看题

题目描述

猜一个数aaa,每次可以提一个问题(x,y)(x,y)(x,y),如果xymod  ax\geq y\mod ax≥ymoda 返回x,否则返回y,你最多询问606060次,然后必须回答出aaa是多少。

二、解法

一道神奇的交互题qwqqwqqwq

首先必须明确一个结论:若xax\geq ax≥a,则 xmod  ax/2x\mod a\leq x/2xmoda≤x/2(证明就不给了,很好意会的)

考虑倍增,l,rl,rl,r都是222的幂次,找到最小的l,rl,rl,r使得 lmod  armod  al\mod a\geq r\mod almoda≥rmoda,这时候一定是返回x的,结合上面的结论,就会发现这时候l<arl< a\leq rl<a≤r

得到这个区间之后,我们可以二分,判断(mid,l)(mid,l)(mid,l)会返回什么,由于一直有l<arl<a\leq rl<a≤r,所以如果返回x,那么就说明midmidmid没被取模,所以aaa一定大于midmidmid,否则midmidmid一定取过模,aaa一定小于等于midmidmid。由于lll是开区间(即aaa不会取到lll),分到l+1=rl+1=rl+1=r是停止,l+1l+1l+1就是最终的答案。

#include <cstdio>
#include <iostream>
using namespace std;
int read()
{
 int x=0,flag=1;char c;
 while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
 while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
 return x*flag;
}
string s;
void work(int &l,int &r)
{
    do
    {
        printf("? %d %d\n",l,r);
        cin>>s;
        if(s[0]=='y') l=r,r<<=1;
    }while(s[0]=='y');
}
int main()
{
    cin>>s;
    while(s.size()!=3)
    {
        int l=0,r=1;
        work(l,r);
        while(l+1<r)
        {
            int mid=(l+r)>>1;
            printf("? %d %d\n",mid,l);
            cin>>s;
            if(s[0]=='x') l=mid;
            else r=mid;
        }
        printf("! %d\n",l+1);
        cin>>s;
    }
}
C202044zxy 发布了236 篇原创文章 · 获赞 12 · 访问量 5812 私信 关注

标签:while,aaa,mid,CF1103B,Game,ax,rl,modulo,mod
来源: https://blog.csdn.net/C202044zxy/article/details/104145464