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\n", cnt); for(int i = 1; i <= n; i++) if(((i >> x) & 1) == f) printf("%d ", i); printf("\n"); 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\n"); for(int i = 1; i <= n; i++) printf("%d%s", mi[i], i==n?"\n":" "); fflush(stdout); }