题解:P16215 [ECUSTPC 2025] 化方为圆
lailai0916 · · 题解
题意简述
通过至多 NotConfirm。
解题思路
先询问
取一个整数方向
点
使用的方向集合为:
根据题目的最新更正,正方形顶点坐标绝对值不超过
下面说明这些方向足以排除所有可区分的正方形。利用旋转,可把正方形的一个顶点写成
正方形在横轴上的连续截距为
令
对前
在
这些情况都有
当
最后处理无法区分的情况。覆盖格点集合相同的正方形,其顶点绝对值排序后只有
若探针全部符合圆且 Bumper。否则再询问 Bumper;其他情况输出 NotConfirm。
当
参考代码
#include <bits/stdc++.h>
using namespace std;
const int d[][2]={{1,1},{2,1},{1,2},{3,1},{1,3},{3,2},{2,3},{1,4},{4,1},{1,5},{5,1},{2,5},{5,2},{3,5},{5,3},{3,8},{8,3}};
bool ask(int x,int y)
{
cout<<'?'<<' '<<x<<' '<<y<<'\n';
cout.flush();
string s;
cin>>s;
if(s=="-1")exit(0);
return s=="IN";
}
void answer(int op)
{
cout<<'!'<<' ';
if(op==0)cout<<"Bumper";
else if(op==1)cout<<"Kevin";
else if(op==2)cout<<"NotConfirm";
cout<<'\n';
cout.flush();
string s;
cin>>s;
if(s=="-2")exit(0);
}
int get(int x,int q)
{
int l=0,r=x+1;
while(l<r)
{
int m=(l+r)/2;
if(1LL*m*m*q>1LL*x*x)r=m;
else l=m+1;
}
return l-1;
}
void solve()
{
bool in=ask(10,0);
int l=in?10:1,r=in?200000:10;
while(l+1<r)
{
int m=(l+r)/2;
if(ask(m,0))l=m;
else r=m;
}
int m=l;
if(m>100000)
{
answer(0);
return;
}
int n=m>=10?6:17;
for(int i=0;i<n;i++)
{
int x=d[i][0],y=d[i][1],q=x*x+y*y;
int a=get(m,q),b=get(m+1,q);
if(1LL*b*b*q<1LL*(m+1)*(m+1))b++;
if(i<6&&!ask(a*x,a*y))
{
answer(1);
return;
}
if(ask(b*x,b*y))
{
answer(1);
return;
}
}
if(m>2)answer(0);
else
{
int cnt=ask(1,2)+ask(2,1)+ask(2,2);
if(cnt==2)answer(0);
else answer(2);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin>>t;
while(t--)solve();
return 0;
}