#P9524. [JOIST 2022] 飞机旅行 / Flights
[JOIST 2022] 飞机旅行 / Flights
题目背景
请使用 C++ 20 提交。
不要引入头文件,并在文件头加入以下内容:
void SetID(int, int);
题目描述
在 JOI 共和国中,有 个机场,编号从 到 。有 条航线,编号从 到 。航线 ()双向连接机场 与机场 。通过若干条航线相连,可以从任意一个机场到达任意另一个机场。对每个机场,连接它与其他机场的航线数量至多为 。
Benjamin 计划在 JOI 共和国旅行。在旅程的最后一天,他想到达温泉所在的机场。游乐园位于机场 ,温泉位于机场 。由于 Benjamin 对航线一无所知,他将与航空公司的工作人员 Ali 沟通。Benjamin 想知道:从游乐园所在的机场出发,到达温泉所在的机场,最少需要乘坐多少条航线。Ali 掌握航线信息,但 Benjamin 并不知道自己应当乘坐哪些航线。
- Ali 为每个机场设置一个 ID 码。ID 码是介于 和 (含)之间的整数。
- Benjamin 得到游乐园所在机场的 ID 码 ,以及温泉所在机场的 ID 码 。
- Benjamin 向 Ali 发送一封电子邮件。该邮件是一串长度 恰好 等于 的字符串,字符串的每个字符均为 或 。
- Ali 给 Benjamin 回一封信。该信是一串长度在 到 (含)之间的字符串,字符串的每个字符均为 或 。
请编写程序,实现航空公司工作人员 Ali 与旅客 Benjamin 的策略。注意:在第 步中,Benjamin 能得到游乐园与温泉所在机场的 ID 码 ,然而 Benjamin 不能获得机场编号 。

实现细节
你需要提交两个文件。
Ali.cpp
该文件应实现 Ali 的策略,并实现下述两个函数。程序应使用预处理指令 #include 引入 Ali.h。
void Init(int N, std::vector<int> U, std::vector<int> V)
该函数用于为每个机场设置 ID 码(见「评分」中的场景说明),每个场景调用 恰好一次。- 参数 为 JOI 共和国中的机场数量。
- 参数 为长度为 的数组,即 分别是航线 ()连接的机场 。
std::string SendA(std::string S)
该函数实现 Ali 给 Benjamin 的回信策略(见「评分」中的场景说明),在调用SendB(见下文)之后、每个场景调用 恰好一次。- 参数 是长度为 的字符串,即 Benjamin 发给 Ali 的电子邮件。
- 函数
SendA应返回一个字符串,即 Ali 给 Benjamin 的回信。 - 返回值的长度必须在 到 (含)之间。若不满足,则判为 Wrong Answer [5]。
- 返回值的每个字符必须为 或 。若不满足,则判为 Wrong Answer [6]。
对每次调用 Init,下述函数必须对每个机场调用一次,总计调用 次:
void SetID(int p, int value)- 参数 表示为机场 设置 ID 码。必须满足 。若不满足,则判为 Wrong Answer [1]。
- 参数
value是 Ali 指定的该机场的 ID 码。必须满足 。若不满足,则判为 Wrong Answer [2]。 - 不允许对同一个 调用多次
SetID。若不满足,则判为 Wrong Answer [3]。 - 当
Init结束时,SetID的调用次数应为 。若不满足,则判为 Wrong Answer [4]。
一旦某次 SetID 调用被判为 Wrong Answer,程序将立即终止。
Benjamin.cpp
该文件应实现 Benjamin 的策略,并实现下述两个函数。程序应使用预处理指令 #include 引入 Benjamin.h。
std::string SendB(int N, int X, int Y)
该函数实现 Benjamin 发给 Ali 的电子邮件策略(见「评分」中的场景说明),在Init调用之后、每个场景调用 恰好一次。- 参数 为 JOI 共和国中的机场数量。
- 参数 为游乐园所在机场的 ID 码。
- 参数 为温泉所在机场的 ID 码。
- 函数
SendB应返回 Benjamin 发给 Ali 的邮件字符串。 - 若返回值不是长度为 的字符串,则判为 Wrong Answer [7]。
- 若返回值的任一字符不是 或 ,则判为 Wrong Answer [8]。
int Answer(std::string T)
该函数应计算从机场 到机场 的最少乘坐航线数(见「评分」中的场景说明),在SendA调用之后、每个场景调用 恰好一次。- 参数 为 Ali 发给 Benjamin 的回信字符串,长度在 到 (含)之间。
- 函数应返回从机场 到机场 所需的最少航线数量。
重要注意事项
- 程序可以实现其他内部使用的函数,或使用全局变量。提交的文件将与评测器一同编译,组成单个可执行文件。为避免与其他文件冲突,所有全局变量与内部函数都应声明在匿名命名空间中。评测时将分别作为 Ali 与 Benjamin 两个进程执行。Ali 进程与 Benjamin 进程 不能共享 全局变量。
- 程序 不得 使用标准输入与标准输出。程序 不得 通过任何方式与其他文件通信。但你可以向标准错误输出调试信息。
评分
一个测试用例由 个场景组成,编号为 到 。每个场景给定如下数据(取值范围见「约束」):
- JOI 共和国的机场数量 。
- 游乐园所在的机场编号 。
- 温泉所在的机场编号 。
- 航线信息 $(U_0, V_0), (U_1, V_1), \dots, (U_{N - 2}, V_{N - 2})$。
对每个场景,依次调用 Init、SendB、SendA、Answer。你的程序应在这些调用中使用合法参数并返回合法值。调用顺序如下:
- 对 ,依次执行步骤 –。
- 调用
Init,参数按场景 的「实现细节」说明设置。 - 调用
SendB,参数按场景 的「实现细节」说明设置。 - 调用
SendA,参数按场景 的「实现细节」说明设置。 - 调用
Answer,参数按场景 的「实现细节」说明设置。
若程序在这些过程中任一处被判为 Wrong Answer,程序将立即终止,并视为未通过该测试用例。

编译与本地测试
你可以从竞赛网页下载包含样例评测器的压缩包,用于本地测试。压缩包中也包含你程序的样例源文件。
样例评测器文件名为 grader.cpp。为测试你的程序,请将 grader.cpp、Ali.cpp、Benjamin.cpp、Ali.h、Benjamin.h 放在同一目录下,并运行以下命令进行编译:
g++ -std=gnu++17 -O2 -o grader grader.cpp Ali.cpp Benjamin.cpp
若编译成功,将生成可执行文件 grader。
注意:实际评测器与样例评测器不同。样例评测器作为单进程执行,从标准输入读取数据并向标准输出写出结果。
输入格式
样例评测器从标准输入读取如下数据。所有输入值均为整数。
(场景 的输入)
(场景 的输入)
(场景 的输入)
每个场景的输入格式如下:
输出格式
如果程序被判为 Wrong Answer [1]–[8] 中的任意一种,样例评测器会输出其类型(引号仅为说明):“Wrong Answer [1]”。
否则,对每个场景,它会输出函数 Answer 的返回值以及 Ali 发给 Benjamin 的字符串的最大长度。样例评测器 不会 检查 Answer 的返回值是否正确。
Scenario 0: Your Answer = 3
Scenario 1: Your Answer = 1
Scenario 2: Your Answer = 4
Scenario 3: Your Answer = 1
Scenario 4: Your Answer = 5
Accepted: Maximum Length = 24
如果你的程序同时满足多种 Wrong Answer 的判定条件,样例评测器只报告其中一种。此外,即使你的程序在后续场景被判为 Wrong Answer [1]–[8],只要在第一个场景未被判错,样例评测器也可能先输出如下中间结果:
Scenario 0: Your Answer = 3
Scenario 1: Your Answer = 1
Scenario 2: Your Answer = 4
Wrong Answer [8]
提示
约束
- 。
- 。
- ()。
- 。
- 。
- 。
- 通过若干条航线相连,可以从任意一个机场到达任意另一个机场。
- 对每个机场,连接它与其他机场的航线数量至多为 。
子任务
1.( 分)。
2.( 分)。
子任务 1 的评分
若你的程序在子任务 的任意场景中被判为 Wrong Answer,则该子任务得分为 。
若你的程序正确回答子任务 的所有测试用例,得分按下述规则计算。设 为 Ali 发给 Benjamin 的字符串的最大长度。
| 的取值 | 得分 |
|---|---|
| 分 | |
| 分 | |
| 分 |
子任务 2 的评分
若你的程序在子任务 的任意场景中被判为 Wrong Answer,则该子任务得分为 。
若你的程序正确回答子任务 的所有测试用例,得分按下述规则计算。设 为 Ali 发给 Benjamin 的字符串的最大长度。注意:若 ,该子任务得分为 。
| 的取值 | 得分 |
|---|---|
| 分 | |
| $52 - 35 \times \log_{10}\!\bigl(\frac{L_2}{70}\bigr)$ 分(向下取整) | |
| 分(向下取整) | |
| 分 | |
| 分 |
样例交互
以下为样例评测器的样例输入与对应的函数调用。在该示例中,Ali 在 Init 中为机场 设置的 ID 码分别为 。
样例输入 1
| Ali 的调用 | Ali 的返回值 | Benjamin 的调用 | Benjamin 的返回值 |
|---|---|---|---|
在该样例中,有 个机场与三条航线:
- 一条连接机场 与机场 的航线;
- 一条连接机场 与机场 的航线;
- 一条连接机场 与机场 的航线。
从机场 到机场 至少需要乘坐 条航线,因此 Answer 应返回 。
注意:SendB 的返回值并不是机场编号 ,而是机场的 ID 码 。
样例输入 2
2
10 0 9
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
15 12 8
0 1
0 2
1 3
1 4
2 5
2 6
3 7
3 8
4 9
4 10
5 11
5 12
6 13
6 14
在该样例中, 个场景:
- 对于第一个场景,
Answer应返回 。 - 对于第二个场景,
Answer应返回 。