P13346 [EGOI 2025] Laser Strike / 激光突击

题目背景

请选择 C++20 提交。

题目描述

Ann 和她的朋友 Kathrin 最近发现了一款新桌游,这款游戏成了她们的最爱:Laser Strike。在这款游戏中,两位玩家需要协作将棋盘上的 $N$ 个棋子全部移除。游戏分为两个阶段。关键在于,Kathrin 并不了解全部信息。为了赢得游戏,Ann 和 Kathrin 必须协作,并且尽量减少交流。 棋盘上有 $N$ 个独特的棋子,编号为 $0$ 到 $N-1$。两位玩家都可以看到这些棋子。此外,棋盘上有 $N-1$ 条连接,每条连接连接一对棋子,使得任意两个棋子之间都可以通过若干条连接到达。换句话说,这些连接构成了一棵树。**只有 Ann 能看到这些连接;Kathrin 并不知道它们。** 在游戏的第一阶段,Ann 决定一个移除棋子的顺序 $l_0, l_1, \ldots, l_{N-2}$,直到只剩下最后一个棋子。这个顺序对 Kathrin 保密。如果 Kathrin 能复现这个顺序,两人就能赢得游戏。每次移除棋子时,需满足如下规则:每次被移除的棋子,必须与仅剩的一个棋子直接连接。换句话说,每次被移除的棋子都必须是当前剩余树中的一个叶子节点。(当 $N-1$ 个棋子都被移除后,最后一个棋子自动被移除,游戏胜利。)Ann 必须选择一个满足上述规则的移除顺序。 Ann 还会写下一条信息给 Kathrin,形式为一个二进制字符串。Ann 可以自选信息长度——信息越短,得分越高。 之后,游戏进入第二阶段。目标是让 Kathrin 按顺序 $l_0, l_1, \ldots, l_{N-2}$ 移除 $N-1$ 个棋子。她会进行 $N-1$ 步操作。在第 $i$ 步操作前,Ann 会告诉 Kathrin 一对整数 $a, b$,满足: * $a < b$; * 这两个棋子 $a$ 和 $b$ 之间在当前剩余棋子中有直接连接; * $a$ 或 $b$ 中有一个就是本轮应被移除的棋子 $l_i$。 注意,对于 Ann 来说,当前树中每个叶子 $l_i$ 都能唯一确定一个连接 $(a, b)$。 然后,Kathrin 会选择移除 $a$ 或 $b$ 中的一个棋子。如果她移除的是正确的叶子 $l_i$,游戏继续;否则游戏失败。 你的任务是同时实现 Ann 和 Kathrin 的策略,使她们能够赢得游戏。 你的程序得分取决于 Ann 在第一阶段写下的信息长度。 ### 实现细节 **这是一道通信题。** 本题为多轮运行题目,你的程序会被执行两次。第一次运行时,实现 Ann 的策略(第一阶段);第二次运行时,实现 Kathrin 的策略(第二阶段)。 输入的第一行包含两个整数 $P$ 和 $N$,其中 $P$ 为 1 或 2(分别表示第一或第二阶段),$N$ 为棋子数量。 后续输入内容取决于阶段: **阶段 1:Ann** 第一行后,接下来 $N-1$ 行描述树的结构。每行两个整数 $a$ 和 $b$($0 \leq a < b \leq N-1$),表示棋子 $a$ 和 $b$ 之间有一条连接。 你的程序应首先输出一个二进制字符串(长度不超过 1000),即 Ann 写给 Kathrin 的信息。若信息长度为 0,输出空行。 然后输出 $N-1$ 个整数 $\ell_0, \ell_1, \ldots, \ell_{N-2}$,每行一个,表示 Ann 希望的叶子移除顺序。该顺序必须满足每次移除的都是当前树的叶子。 **阶段 2:Kathrin** 第一行后,下一行输入为 Ann 的二进制信息。 接下来有 $N-1$ 轮交互,每轮代表 Kathrin 的一次操作。 在第 $i$ 轮,你的程序应首先读入两个整数 $a$ 和 $b$($0 \leq a < b \leq N-1$)。其中一个是当前应移除的叶子 $\ell_i$,另一个是唯一与其直接连接的剩余棋子。然后,你的程序应输出 $\ell_i$,即 Kathrin 选择移除该叶子。如果输出不是正确的叶子,游戏失败,本测试点判为 Wrong Answer。 ### 细节说明 两次运行的总时间不得超过时限,否则会被判为 TLE。 每次输出后请及时刷新标准输出,否则可能被判为 TLE。Python 用 `input()` 读入时自动刷新;C++ 可用 `cout

输入格式

见实现细节。

输出格式

见实现细节。

说明/提示

### 样例说明 注意,以下样例 $N=7$,仅为说明方便,并非正式测试用例。正式评测所有用例均有 $N=1000$。 在样例中,Ann 得到如下树结构。在第一阶段,Ann 读入树,选择二进制串 "0110" 发送给 Kathrin,并选择移除顺序 $[\ell_0, \ell_1, \ldots, \ell_{N-2}] = [5, 3, 2, 6, 4, 0]$。第二阶段,Kathrin 收到 Ann 的二进制串 "0110",随后收到对 $(1,5)$ 并选择移除 5,接着收到对 $(2,3)$ 并移除 3,依此类推。下图展示了交互过程: ![](https://www.luogu.com.cn/fe/api/problem/downloadAttachment/r5zy0gd2) ### 测试工具 为方便测试,官方提供了一个简单的工具。见 Kattis 题目页面底部的“attachments”。该工具可选,正式评测器与该工具不同。 用法:准备一个输入文件(如 "sample1.in"),文件第一行为 $N$,接下来 $N-1$ 行描述树结构,格式同阶段 1。例如: ``` 7 0 1 1 2 2 3 0 4 0 6 1 5 ``` 对于 Python 程序(如 solution.py,通常用 `pypy3 solution.py` 运行),可用如下命令: ``` python3 testing_tool.py pypy3 solution.py < sample1.in ``` C++ 程序编译后(如 `g++ -g -O2 -std=gnu++23 -static solution.cpp -o solution.out`),可用如下命令: ``` python3 testing_tool.py ./solution.out < sample1.in ``` ### 约束与评分 * $N = 1000$ * 对所有连接,$0 \leq a < b \leq N-1$ 你的解答将在一组测试组上进行评测,每组包含若干测试用例。要获得该测试组分数,你需要通过该组所有测试用例。 | 组别 | 满分 | 限制 | | :-: | :-: | :-: | | 1 | 8 | 树为星形,即除一个节点外其余全为叶子 | | 2 | 9 | 树为链形,即除两个叶子外其余每个节点度数为 2 | | 3 | 21 | 树为“星形加链”,即所有节点度为 1 或 2,只有一个节点度大于 2 | | 4 | 36 | 任意两点间距离不超过 10 | | 5 | 26 | 无额外限制 | 对于每个通过的测试组,你的得分按下式计算: $$\text{score} = S_g \cdot (1 - 0.3 \cdot \log_{10} \max(K, 1))$$ 其中 $S_g$ 为该测试组满分,$K$ 为该组任一测试用例中 Ann 的消息最大长度。每组得分四舍五入取整。 下表给出若干 $K$ 时的总分示例,若所有测试组都通过且 $K$ 如下: | $K$ | 1 | 5 | 10 | 50 | 100 | 500 | 1000 | | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | 得分 | 100 | 79 | 70 | 49 | 39 | 20 | 11 | 翻译由 ChatGPT-4.1 完成。