这是一道交互题,今天第一次写,训练赛时,一点不懂,还理解错题意了。
题目
题解
题目意思其实就是,你在代码中设置一种询问方式,不断打印出来,运行时,以你的输入作为回答。当你的回答已经足以判断是那种类型时,就打印 ! 1/2
,这里对于询问的次数有限制,所以需要思考,用那种方式询问。
起初我想的时,如果我能得到一个有边的询问,这不就好办了,沿着这个边就能得到答案。可怎么才能得到,关键来了:题中所给的⌈n/2⌉+3
,是别有深意的
这是从题解上截的图片。但是里面,又有关键的一点没提。
如果n为偶数的话,自然就可以顺利AC。可惜不是,所以你就需要把末尾n和1再询问一次,没边就肯定是链,有边再询问,还想像上面p1,p2,这样询问吗?
哈哈,那就错了,你的n和1本来就多询问了一次,再询问三次也不会超啊,因为是向上取整,但提交就错了,我也不懂为啥,只好换了一种, 用n和前面两个数分别询问,如果和两个都有边,那就是莲花啦
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int ask(int u,int v)
{
cout<<"? "<<u<<" "<<v<<'\n';
fflush(stdout);
int i;
cin>>i;
return i;
}
void check(int u,int v)
{
for(int i=1;i<=n;i++)
if(i!=u&&i!=v)
{
int p=ask(i,u),q=ask(i,v);
if(p==1)
{
for(int j=1;j<=n;j++)
if(j!=u&&j!=v&&j!=i)
{
if(ask(j,u)==1)
cout<<"! 2"<<'\n';
else cout<<"! 1"<<'\n';
return;
}
}
else if(q==1)
{
for(int j=1;j<=n;j++)
if(j!=u&&j!=v&&j!=i)
{
if(ask(j,v)==1)
cout<<"! 2"<<'\n';
else cout<<"! 1"<<'\n';
return;
}
}
else cout<<"! 1"<<'\n';
fflush(stdout);
return ;
}
}
void solve ()
{
cin>>n;
for(int i=1;i<n;i+=2)
{
if(ask(i,i+1))
{
check(i,i+1);
return ;
}
}
if(ask(n,1))
{
if(ask(n,n-1)&&ask(n,n-2))
cout<<"! 2"<<'\n';
else
cout<<"! 1"<<'\n';
}
else
cout<<"! 1"<<'\n';
fflush(stdout);
}
int main()
{
int t;
cin>>t;
while(t--)
{
solve();
}
}