Codeforces Round #720 (Div. 2)

考试情况

少了一道题多了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;
}

上一篇:第7章学习小结


下一篇:折半查找平均查找长度推导