QOJ.ac

QOJ

Time Limit: 4 s Memory Limit: 1024 MB Total points: 100 Difficulty: [show] Interactive

#18254. 座位安排

Statistics

本届 EGOI 的闭幕式将有 $N$ 位重要宾客出席。他们都需要按照非常特定的顺序坐在前排,以符合外交礼仪的所有细节。确定正确的座位顺序让 Noemi 熬了两个通宵。

Veronica 正在监督闭幕式。她的众多职责之一是确保前排座位上有正确的名字标牌。只有一个小问题:Noemi 从未告诉她正确的座位顺序,而现在 Noemi 已经找不到了。幸运的是,摄影师 Dorka 有一个可能派上用场的应用程序(App)。

Dorka 必须准备好她的相机,以便为前排的宾客拍摄一些特定的照片。为了进行设置,她需要知道每张照片有多宽,因此 Noemi 为她制作了一个 App,可以快速输出她需要的信息。Veronica 现在想利用这个 App 来找到正确的座位安排。

这 $N$ 位重要宾客的编号为 $0$ 到 $N - 1$。前排的座位也从左到右编号为 $0$ 到 $N - 1$。对于每个 $I$($0 \le I \le N - 1$),令 $g_I$ 表示应该坐在座位 $I$ 的宾客,并令 $s_I$ 表示宾客 $I$ 应该坐的座位。

图 1:有 5 位宾客的一排。对于这一排,$g = [3, 1, 0, 2, 4]$ 且 $s = [2, 1, 3, 0, 4]$。

该 App 的工作原理如下:

  • Dorka 输入恰好三位不同宾客的编号 $I, J, K$。
  • App 会告诉她,如果这三位选定的宾客都在照片中,照片中将显示的最少宾客人数。形式化地,App 将显示值 $\max(s_I, s_J, s_K) - \min(s_I, s_J, s_K) + 1$。

例如,参见图 1 中所示的情况:

  • 宾客 $I = 0, J = 2, K = 4$ 分别在座位 $s_I = 2, s_J = 3, s_K = 4$。如果 Dorka 选择他们,App 将显示值 $\max(2, 3, 4) - \min(2, 3, 4) + 1 = 3$。 换句话说,包含宾客 0、2 和 4 的最窄照片恰好包含这三位宾客。
  • 宾客 $I = 0, J = 4, K = 3$ 分别在座位 $s_I = 2, s_J = 4, s_K = 0$。如果 Dorka 选择他们,App 将显示值 $\max(2, 4, 0) - \min(2, 4, 0) + 1 = 5$。 换句话说,包含这三位给定宾客的照片必须包含所有 5 位宾客。

请使用 Dorka 的 App 帮助 Veronica 确定正确的座位顺序。更具体地说,你的程序应该确定并输出序列 $g_0, g_1, \dots, g_{N-1}$。总是恰好有两个正确答案(其中一个是另一个的翻转),你可以输出其中任意一个。你的得分将取决于你的解决方案对 App 进行的询问次数。

实现细节

这是一个交互式问题。你的程序将使用标准输入和输出与交互器(grader)按照以下格式进行通信。

你的程序应该首先读取一行输入,其中包含一个正整数 $T$,表示接下来的测试用例数量。

对于每个测试用例,你的程序应该首先读取一行输入,其中包含一个正整数 $N$,表示座位的数量,这也是宾客的数量。

要进行一次询问,你的程序应该输出一行格式为 ? I J K 的内容,其中 $0 \le I, J, K \le N - 1$ 是三个不同的整数。

在进行询问后,你的程序应该读取一行,其中包含一个正整数,即对你询问的回答。

要回答正确的座位顺序,你的程序应该输出一行格式为 ! g_0 ... g_{N-1} 的内容。

在解决所有 $T$ 个测试用例后,你的程序应该正常终止。

请注意,CMS 中用于测试你的解决方案的官方交互器可能是自适应的(adaptive)。也就是说,对于某些测试用例,宾客的排列并不是预先确定的。相反,交互器可能会根据你的程序已经提出的询问,来决定使用剩下哪些排列。

刷新缓冲区(Flushing)。如果你没有使用提供的模板,请确保在打印每行后刷新标准输出,否则你的程序可能会被判定为不正确(Not correct)。在 Python 中,如果你使用 input() 读取行,这会自动发生,你可以使用 print(..., flush=True) 来强制刷新。在 C++ 中,cout << endl; 除了打印换行符外还会刷新;如果使用 printf,请使用 fflush(stdout)

数据范围

  • $1 \le T \le 10$。
  • $N$ 将为 $5$(仅限样例)、$8$、$40$ 或 $2000$。
  • 对于每个测试用例,你最多可以进行 $10\,000$ 次询问。

子任务

你的程序将在分为多个子任务的若干测试用例上进行测试。要获得某个子任务的分数,你必须正确解决它包含的所有测试用例。

  • 子任务 0 [0 分]:样例($N = 5$)。
  • 子任务 1 [9 分]:$N = 8$。
  • 子任务 2 [11 分]:$N = 2000$,且宾客 0 和 1 相邻而坐。
  • 子任务 3 [15 分]:$N = 40$。
  • 子任务 4 [65 分]:$N = 2000$。

对于子任务 1 和 2,任何正确解决所有测试用例的解决方案都将获得全部满分。

对于子任务 3 和 4,你的解决方案必须正确解决所有测试用例才能获得任何分数,你的分数将取决于 $Q_s$,即你的解决方案在解决单个测试用例时所需的最大询问次数。令 $X_s = \max(1, Q_s/N)$。子任务 3 和 4 的分数计算如下:

$$\text{score}_3 = \min\left(15, 3 + \frac{19}{X_s^{1.5}}\right), \quad \text{score}_4 = \min\left(65, 3 + \frac{91}{X_s^{1.5}}\right)$$

每个子任务的 $\text{score}_s$ 值将四舍五入到最接近的整数,你的总分是这些分数的总和。为了获得满分,你需要在子任务 3 中使用最多 $55$ 次询问,在子任务 4 中使用最多 $2597$ 次询问。下面显示了 $Q_s$ 的示例值以及子任务 3 和 4 的对应得分。

$Q_s$ 55 56 60 70 80 100 150 10000
$\text{score}_3$ 15 14 13 11 10 8 6 3
$Q_s$ 2597 2800 3000 4000 5000 6000 8000 10000
$\text{score}_4$ 65 58 53 35 26 21 14 11

样例

输入样例 1

1
5
3
3
5

输出样例 1

? 0 2 4
? 3 0 1
? 0 4 3
! 3 1 0 2 4

说明

样例输入包含一个测试用例($T = 1$),其中有 $N = 5$ 位宾客。该测试用例中隐藏的宾客配置对应于图 1。

样例解决方案进行的第一次询问是 0 2 4。对该询问的回答 3 告诉我们,这些宾客以某种未知的顺序坐在相邻的三个连续座位上。

对第二次询问的回答 3 告诉我们关于宾客 3、0 和 1 的相同信息。

我们现在可以推断出宾客 0 必须坐在中间,宾客 2 和 4 在一侧,宾客 1 和 3 在另一侧。

在第三次询问之后,我们已经可以确定宾客必须以顺序 [3, 1, 0, 2, 4] 或相反的顺序 [4, 2, 0, 1, 3] 坐下。我们可以输出这两种顺序中的任意一种。

CMS 中的代码模板与评测细节

我们强烈建议使用为 C++ 和 Python 提供的代码模板。这些模板会检查与交互器的通信是否成功,并在不成功时优雅地终止。

如果你不使用提供的模板,在你的解决方案不正确的情况下,CMS 可能会显示错误的评测结果。例如,你可能会收到“Execution killed by signal”(由信号终止)或“Execution timed out (wall clock limit exceeded)”(超时),而不是“Output isn't correct”(输出不正确)。

我们还建议在提交之前使用测试工具(见下文)在本地测试你的解决方案。测试工具会检查你解决方案的输出,并报告无效询问的使用情况。

测试工具

为了方便测试你的解决方案,我们提供了一个可以从 CMS 下载的简单工具。该工具是可选使用的。请注意,CMS 上的官方交互器与该测试工具不同。

要使用该工具,你需要一个输入文件。你可以使用提供的示例输入 seatingplan.input0.txt 或制作你自己的输入。输入文件应首先包含一行,其中有测试用例的数量 $T$,然后每个测试用例有两行:一行包含数量 $N$,然后一行包含数字 $g_0, g_1, \dots, g_{N-1}$。

对于 Python 程序,假设为 seatingplan.py(通常运行为 pypy3 seatingplan.py),按如下方式运行测试工具:

python3 testing_tool.py pypy3 seatingplan.py < seatingplan.input0.txt

对于 C++ 程序,首先编译你的解决方案:

g++ -DEVAL -std=gnu++20 -O2 -pipe -static -s -o seatingplan seatingplan.cpp

然后运行测试工具:

python3 testing_tool.py ./seatingplan < seatingplan.input0.txt

Editorials

IDTypeStatusTitlePosted ByLast UpdatedActions
#1784EditorialOpenOfficial EditorialAnonymous2026-05-21 14:22:04View

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.