专栏文章
题解:CF2133C The Nether
CF2133C题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mio4tzwq
- 此快照首次捕获于
- 2025/12/02 13:23 3 个月前
- 此快照最后确认于
- 2025/12/02 13:23 3 个月前
题目链接
分析
首先,对于每个点可以查出以它为起点,集合中包含所有点时的最长路径,记为 。最长路径的起点即为 最大的 。
考虑如何找到一个点在最长路径上的后继。可以将点按照 分层。设当前找到的最长路径上的最后一个点为 。枚举最长路径长度为 的所有点。若 在集合中排除同一层中除当前点外的所有点时,最长路径长度仍为 ,则当前点是 在最长路径上的后继。
第一遍查询 次,第二遍最坏情况每个点查一次,也是 次,总数不超过 次。
Code
CPP#include <bits/stdc++.h>
using namespace std;
constexpr int N = 505;
int len[N];
vector<int> ans, vec, lth[N];
int main()
{
// freopen(".in", "r", stdin), freopen(".out", "w", stdout);
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int T; cin >> T;
for (int $ = 0; $ < T; ++ $)
{
int n; cin >> n;
int tmp, max_lth = 0;
for (int i = 1; i <= n; ++ i)
{
cout << "? " << i << ' ' << n;
for (int j = 1; j <= n; ++ j) cout << ' ' << j;
cout << endl, cin >> tmp, lth[tmp].push_back(i), len[i] = tmp, max_lth = max(max_lth, tmp);
}
ans.push_back(lth[max_lth].back());
for (int i = max_lth; i > 1; -- i)
{
int now = ans.back(); bool f = true;
for (int j : lth[i - 1])
{
vec.clear();
for (int k = 1; k <= n; ++ k) if (len[k] != i - 1 || k == j) vec.push_back(k);
cout << "? " << now << ' ' << vec.size();
for (int k : vec) cout << ' ' << k;
cout << endl, cin >> tmp;
if (tmp == i) { f = false, ans.push_back(j); break; }
}
if (f) ans.push_back(lth[i - 1].back());
}
cout << "! " << ans.size();
for (int i : ans) cout << ' ' << i; cout << endl;
ans.clear();
for (int i = 1; i <= max_lth; ++ i) lth[i].clear();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...