一、题目
题目描述
猜一个数a,每次可以提一个问题(x,y),如果x≥ymoda 返回x
,否则返回y
,你最多询问60次,然后必须回答出a是多少。
二、解法
一道神奇的交互题qwq
首先必须明确一个结论:若x≥a,则 xmoda≤x/2(证明就不给了,很好意会的)
考虑倍增,l,r都是2的幂次,找到最小的l,r使得 lmoda≥rmoda,这时候一定是返回x
的,结合上面的结论,就会发现这时候l<a≤r
得到这个区间之后,我们可以二分,判断(mid,l)会返回什么,由于一直有l<a≤r,所以如果返回x
,那么就说明mid没被取模,所以a一定大于mid,否则mid一定取过模,a一定小于等于mid。由于l是开区间(即a不会取到l),分到l+1=r是停止,l+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
私信
关注