[CF1267I] Intriguing Selection 题解

考虑 n=3n=3 的情况,假设我们第一次询问 (a,b)(a,b),得到 a<ba<b,如果第二次询问仍然包含 aa 的话就可能得到前 33 名的排序了。

接着询问 bb 不好做,于是我们考虑询问另一个不相交的 (c,d)(c,d),得到 b<db<d,我们再询问一次 (a,c)(a,c) 的大小关系,不妨设 a<ca<c,此时我们可以询问 aa 与其他所有人的大小关系,因为存在两个比它大的大小关系不确定。

考虑这样一个算法,我们维护一个初始包含所有数的队列,每次依次取出 a,b,c,da,b,c,d 四个数,按照如上方法询问,之后再按 b,c,db,c,d 的顺序放回,这样一直做到只剩三个数为止,此时我们一定能保证这三个数中我们只知道一对的大小关系,结束即可。

#include <bits/stdc++.h>
using namespace std;
int n, mp[210][210];
int query(int a, int b) {
if (mp[a][b] != -1)
return mp[a][b];
cout << "? " << a << " " << b << '\n';
cout.flush();
char c;
cin >> c;
return mp[a][b] = c == '<';
}
int main() {
cin.tie(0)->sync_with_stdio(0);
int T;
cin >> T;
while (T--) {
cin >> n;
n <<= 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
mp[i][j] = -1;
vector<int> v;
for (int i = 1; i <= n; i++)
v.push_back(i);
while (v.size() > 3) {
int a = v.back();
v.pop_back();
int b = v.back();
v.pop_back();
int c = v.back();
v.pop_back();
int d = v.back();
v.pop_back();
if (!query(a, b))
swap(a, b);
if (!query(c, d))
swap(c, d);
if (!query(a, c))
swap(a, c), swap(b, d);
for (int i = 1; i <= n; i++) {
if (i != a)
query(i, a);
}
v.push_back(b), v.push_back(c), v.push_back(d);
}
cout << "! " << '\n';
cout.flush();
}
return 0;
}
// 1 6 4 3 2 5
posted @   swiftqwq  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示