考试情况
少了一道题多了15分钟,依然很自闭…
A题 做了非常久,错误点在于普遍存在的一个观念:如果n是a的倍数且n是b的倍数,那么n就是a*b的倍数。很明显能举出反例30是10和15的倍数但并不是150的倍数。所以就推翻了之前的做法,修改过后完美AC
B题 也有些棘手,依然存在一个观念:只有两个数成倍数关系,那么他们才互质,这显然也是错误的…故修改过后,即使有一点小常数,但也是AC了
C题 是交互题,样例就没给完整,导致啥都看不懂,然后就没有然后了…
题解
C
做得第二道交互题,依然很不熟练
交互题中样例可能根本没给全!!
这道题的大致思路分为两步
要尽可能减少询问次数,依然可以用交互题惯用的方式二分
首先通过二分不断的询问两个数,从而求解出一个数的具体值
接着通过这个数的具体值,求出整个数组的值
思路大致就是这样
至于怎么通过比较去求解每个数的具体值,可以参照代码自己悟一悟解释起来太麻烦
code
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int T,n,p[N];
int main()
{
cin>>T;
while(T--)
{
cin>>n;
int l=0,r=n-1;
while(l<r)
{
int mid=(l+r+1)>>1;
if(mid>=n) break;
printf("? 1 1 2 %d\n",mid);
int x;
cin>>x;
if(x==mid+1) l=mid;
else r=mid-1;
}
p[2]=l+1;
if(p[2]>n/2)
for(int i=1;i<=n;i++)
{
if(i==2) continue;
printf("? 2 %d 2 1\n",i);
int x;
cin>>x;
if(x<p[2]) p[i]=x;
else
{
printf("? 1 2 %d %d\n",i,n-1);
cin>>x;
p[i]=x;
}
}
else
for(int i=1;i<=n;i++)
{
if(i==2) continue;
printf("? 1 2 %d %d\n",i,n-1);
int x;
cin>>x;
if(x>p[2]) p[i]=x;
else
{
printf("? 2 %d 2 1\n",i);
cin>>x;
p[i]=x;
}
}
printf("! ");
for(int i=1;i<=n;i++) printf("%d ",p[i]);
printf("\n");
}
return 0;
}