QOJ.ac

QOJ

時間限制: 2 s 記憶體限制: 256 MB 總分: 10 互動

#216. Sonda [A]

统计

巴伊特太空署(Bajtocka Agencja Kosmiczna)几年前发现了小行星 BA-1T。巴伊塔扎(Bajtazar)负责监督一项无人探测任务,旨在将该行星上的矿物样本带回地球。不幸的是,由于软件开发人员的疏忽,探测器系统中存在许多错误,导致与探测器的通信变得非常困难。尽管如此,巴伊塔扎仍必须完成这项任务。

巴伊塔扎在小行星上确定了 $n$ 个关键点,需要从中采集矿物样本。这些点用 $1$ 到 $n$ 的自然数编号,探测器最初位于 $1$ 号点。这些点之间存在一定数量的双向连接。如果探测器位于连接的一端,它可以移动到另一端。不幸的是,有关连接的信息被编码在探测器中,而巴伊塔扎并不知晓。幸运的是,他记得探测器可以从任何点到达任何其他点,可能需要经过其他中间点。

理论上,事情很简单。巴伊塔扎可以向探测器发出移动到任何其他点的指令,探测器应告知巴伊塔扎移动是否成功。

然而,在实践中,由于软件错误,情况变得有些复杂。首先,如果巴伊塔扎指示移动到探测器当前所在的点,设备将会爆炸,导致研究无法进行。如果与目标点之间不存在直接连接,探测器将不会改变位置,巴伊塔扎会收到否定响应。如果连接存在,探测器将移动到该点。但由于另一个软件错误,巴伊塔扎只有在探测器执行了偶数次成功移动时才会收到肯定响应。否则,他将收到否定响应——与不存在连接时的响应完全相同。

探测器还可以检查其当前所在的点(即收集矿物样本)。为了保持研究的有序性,每个点必须且只能被检查一次。

由于探测器距离地球很远,发送指令非常耗时,因此巴伊塔扎最多只能发送一百万次移动指令。

请帮助巴伊塔扎完成研究,并恢复太空署对任务的信心!

交互方式

本题为交互题。你需要编写一个程序,通过提供的库与探测器进行通信。为此,请使用以下指令包含头文件 sonlib.h

#include "sonlib.h"

该库提供以下函数:

  • int GetN() – 返回参数 $n$ ($3 \le n \le 400$),即小行星上关键点的数量。
  • int GetSubtask() – 返回参数 $s$ ($0 \le s \le 3$),详见下文“子任务”部分。
  • int MoveProbe(int v) – 指示探测器移动到点 $v$。随后:
    • 如果未满足 $1 \le v \le n$ 的条件、探测器已位于点 $v$ 或程序之前已调用过 $1\,000\,000$ 次 MoveProbe,则程序将被终止,测试结果为错误。
    • 如果当前点与 $v$ 之间不存在连接,探测器不会移动,函数返回 $0$。
    • 如果连接存在,探测器将移动到点 $v$。如果这是探测器执行的第偶数次成功移动(例如第 2 次或第 10 次),函数返回 $1$。否则,函数返回 $0$。
  • void Examine() – 指示探测器检查其当前所在的点。随后:
    • 如果探测器尝试检查一个已经检查过的点,程序将被终止,测试结果为错误。
    • 如果探测器已检查过每个点且仅检查过一次,库将终止程序并判定解决方案正确。

库通过调用 exit(0) 来终止程序。

探测器初始位于点 $1$。连接允许访问所有点(图是连通的)。连接在程序运行开始时即已确定,即库不会根据之前的查询更改连接。

严禁任何试图影响评测库内部运作的行为。

子任务

在所有测试中,$3 \le n \le 400$。你的程序最多可以调用 MoveProbe 函数 $1\,000\,000$ 次。

部分分数可以通过解决特定图结构的子任务获得。函数 GetSubtask 返回的参数 $s$ 可用于识别这些子任务:

  • 如果 $s = 0$,图不需要满足任何额外假设。
  • 如果 $s = 1$,连接图是一个完全二分图。点集可以划分为两个(未知的)非空子集 $A$ 和 $B$。存在 $|A| \cdot |B|$ 条连接,每条连接连接 $A$ 中的一个点和 $B$ 中的一个点。
  • 如果 $s = 2$,保证存在三条特定连接:$(1, 2)$、$(2, 3)$ 和 $(3, 1)$。
  • 如果 $s = 3$,每个点恰好与另外两个点相连。

你可以假设同一测试组内的每个测试用例具有相同的 $s$ 值。

样例

样例 1

GetN()
4

样例 2

GetSubtask()
0

说明

在示例测试中,存在以下连接:$(1, 2), (1, 3), (2, 3), (2, 4)$。注意,在此测试中 $s$ 可能为 $0$ 或 $2$。

调用函数 返回值 探测器新位置 成功移动次数 说明
GetN() 4 1 0 共有 4 个关键点。
GetSubtask() 0 1 0 参数 $s$ 为 0。
Examine() 1 0 检查点 1。
MoveProbe(4) 0 1 0 点 1 与点 4 无连接。
MoveProbe(2) 0 2 1 探测器移动。这是第 1 次成功移动(奇数)。
MoveProbe(3) 1 3 2 第 2 次成功移动(偶数)。
Examine() 3 2 检查点 3。
MoveProbe(2) 0 2 3
Examine() 2 3 检查点 2。
MoveProbe(4) 1 4 4
Examine() 所有点均已检查。程序结束,测试通过。

巴伊塔扎总共执行了 5 次 MoveProbe 指令,未超过 $1\,000\,000$ 次的限制。

详细实现

示例错误解决方案和示例库可在 SIO 的“文件”部分找到。库的行为可能与用于评测的库不同,仅用于展示交互方式。

解决方案 son.cpp 可以通过以下方式编译:

g++ -O3 -static -o son son.cpp sonlib.cpp -std=c++17

请确保 sonlib.hsonlib.cpp 与你的解决方案位于同一文件夹中。

编译后,库通过标准输入读取图信息。输入的第一行应包含三个数字 $n, m, s$,分别表示关键点数量、连接数量和子任务编号。接下来的 $m$ 行,每行包含两个数字,表示连接的两个端点。示例测试对应的输入文件为 son0.in

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.