Codeforces Round 967 (Div. 2) - C
题意概述
这是一个交互题。
有一棵有 \(n\) 个节点的树,节点编号从 \(1\) 到 \(n\) ,并要求你使用以下类型的查询来猜测它:
? a b
会告诉你哪个节点 \(x\) 在点 \(a\) 和 \(b\) 之间(\(|d(a,x) - d(b,x)|\) 的值最小),其中 \(d(x,y)\) 是节点 \(x\) 和 \(y\) 之间的距离。如果存在不止一个这样的节点,那么会告诉你哪个节点在哪一个 \(x\) 使 \(d(a,x)\) 最小。
用最多 \(15n\) 次查询找出树的结构。
思路
对于每一个 \(n\) 我们可以递归搜索节点编号 \(p\) 的点和 \(i\) 之间的节点,得到的值为 \(w\) 若 \(w\) 和 \(p\) 相等就在 \(p\) 和 \(i\) 之间连一条边,否则就继续递归 \(w\) 和 \(i\),初始时 \(p\) 等于 \(1\),\(2 \le i \le n\)。对于每次输出使用 fflush(stdout);
清空缓存。输出格式! a1 b1 a2 b2……
。
代码
#include <bits/stdc++.h>
#define ll long long
#define N 100001
#define mod 998244353
#define ios std::ios::sync_with_stdio(false)
#define itie std::cin.tie(0)
#define otie std::cout.tie(0)
std::mt19937_64 mrand(std::random_device{}());
int Test;
std::vector<int> a, b;
inline void solve(int p, int i) {
std::cout << "? " << p << " " << i << std::endl;
fflush(stdout);
int w;
std::cin >> w;
if (w == p) {
a.push_back(p),
b.push_back(i);
return;
}
solve(w, i);
}
int main() {
std::cin >> Test;
for ( ; Test--; ) {
int n;
std::cin >> n;
a.clear();
b.clear();
for (int i = n; i >= 2; i--)
solve(1, i);
std::cout << "! ";
for (int i = 0; i < n - 1; i++)
std::cout << a[i] << " " << b[i] << " ";
puts("");
fflush(stdout);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现