CF1363D Guess The Maximums

Sol

考虑先找到最大值所在位置,设位置为 \(pos\),最大值为 \(mx\)

那么除了 \(pos\) 所在的集合,其他的集合答案均为 \(mx\)

最后用一次操作找到 \(pos\) 外的集合的答案即可。

一共使用了 \(12\) 次操作。

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define pf push_front
#define desktop "C:\\Users\\incra\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
	if (y > x) return x = y,true;
	return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
	if (y < x) return x = y,true;
	return false;
}
LL power (LL a,LL b,LL p) {
	LL ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return ans;
}
int fastio = (IOS,0);
// #define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 1010;
int n,m;
int a[N];
int len[N];
int id[N];
int ans[N];
int query (int l,int r) {
	cout << "? " << r - l + 1 << ' ';
	for (int i = l;i <= r;i++) cout << i << ' ';
	cout << endl;
	int ans;
	cin >> ans;
	return ans;
}
void mian () {
	memset (id,0,sizeof (id));
	cin >> n >> m;
	for (int i = 1;i <= m;i++) {
		cin >> len[i];
		for (int j = 1;j <= len[i];j++) {
			int x;
			cin >> x;
			id[x] = i;
		}
	}
	int l = 1,r = n;
	int mx = query (1,n);
	while (l < r) {
		int mid = l + r + 1 >> 1;
		if (query (mid,n) == mx) l = mid;
		else r = mid - 1;
	}
	int res = -1;
	if (id[l]) {
		cout << "?     " << n - len[id[l]] << ' ';
		for (int i = 1;i <= n;i++) {
			if (id[i] != id[l]) cout << i << ' ';
		}
		cout << endl;
		cin >> res;
	}
	cout << "! ";
	for (int i = 1;i <= m;i++) {
		if (i == id[l]) cout << res << ' ';
		else cout << mx << ' ';
	}
	cout << endl;
	string _;
	cin >> _;
}
int main () {
	int T = 1;
	cin >> T;
	while (T--) mian ();
	return 0;
}
posted @ 2025-04-10 14:30  incra  阅读(18)  评论(0)    收藏  举报