CF745 D 交互题 思维 二进制分解

现有一矩阵
你可以做出不超过20个询问 每个询问 要求输入列号,可以询问矩阵上每行上你给的列之中的最小值
让你最后输出该矩阵每行的不包括对角线位置上的最小值
考虑询问如何分组,考虑二分,以二进制位来分组 那么最多不超过2log(n)次询问就能通过比较得到每行的最小值
注意这里的最重要的问题是如何排除对角线,在比较最小值时,如果当前的行号是对角线上且被包括在当前组中 则抛弃该组结果

#include <bits/stdc++.h>
using namespace std;

int n;
int a[1010];
int mi[1010];
int main()
{
	memset(mi, 0x3f, sizeof(mi));
	scanf("%d", &n);
	int f = 0;
	int x = 0;
	while((1 << x) <= n)
	{
		int cnt = 0;
		for(int i = 1; i <= n; i++)
			if( ((i >> x) & 1) == f)
				cnt++;
		if(!cnt)
			continue;
		printf("%d
", cnt);
		for(int i = 1; i <= n; i++)
			if(((i >> x) & 1) == f)
				printf("%d ", i);
		printf("
");
		fflush(stdout);
		for(int i = 1; i <= n; i++)
		{
			int t;
			scanf("%d", &t);
			if(((i >> x) & 1) != f)
				mi[i] = min(mi[i], t);
		}
		f^=1;
		if(f == 0)
			x++;
	}
	printf("-1
");
	for(int i = 1; i <= n; i++)
		printf("%d%s", mi[i], i==n?"
":" ");
	fflush(stdout);

}

原文地址:https://www.cnblogs.com/Yumesenya/p/7449900.html