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);
    }
}

作者:笙竺

出处:https://www.cnblogs.com/shengzhu/p/18377713

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   笙竺  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示