#P10628. [JOI Open 2024] 图书馆 3

    ID: 10061 Type: RemoteJudge 1000ms 1024MiB Tried: 0 Accepted: 0 Difficulty: 6 Uploaded By: Tags>2024交互题Special JudgeJOI

[JOI Open 2024] 图书馆 3

题目背景

由于洛谷评测系统的限制,实际提交时,不需要引入 library3.h\texttt{library3.h}。你需要在代码中添加:

void answer(std::vector<int>);
int query(std::vector<int>);

请使用 C++ 20 提交,不保证使用其他标准提交能够通过。

题目描述

几百年的时光弹指一瞬,JOI 城已然是一片废墟。IOI 酱——一个探险家,正在探索图书馆的故址。由探索结果得知:

  • JOI 城的图书馆中有一个水平的书架,上面有 NN位置来放书,从左到右依次编号为 0N10\sim N-1。一个位置只能放一本书。
  • NN 本书放在书架上,编号为 0N10\sim N-1
  • 定义 NN 本书的一个摆放为一种将 NN 本书放在 NN 个位置上的方式。
  • 存在 NN 本书的一个正确摆放,其中第 BiB_i0iN10\le i\le N-1)本书放在位置 ii 上,其中 BiB_i 两两不同。

书的摆放总会改变,而这个图书馆是通过不断重复以下步骤来将书还原成正确摆放的:

操作xx 是最左边的书,满足 xx 的位置与它在正确摆放中的位置不同。令 yyxx 正确位置上的书,交换 x,yx,y

尽管 IOI 酱找到了许多旧书,她无法得知书的正确摆放。然而,她发现了一台旧机器,可以执行上面的操作。如果指定一个摆放并向机器发起询问,机器就会回答从当前摆放到正确摆放,需要重复执行多少次操作。IOI 酱想要利用这台机器,获得书的正确摆放。由于机器过于老旧,她最多只能询问 50005\, 000 次。

你需要写一个程序。给定书架的信息,通过最多 50005\,000 次询问,找出书的正确摆放。

【实现细节】

这是一道交互题,你只需要提交一个文件(library3.cpp)。

你需要在文件中引入 library3.h,并实现以下函数:

  • void solve(int N)
    该函数在每个测试点中被调用恰好一次。
    • 参数 NN 代表书的数量。

library3.cpp 中,你可以调用以下函数:

  • int query(const std::vector<int> a)
    IOI 酱用这个函数向机器发起询问。

    • 参数 a 为一个长度为 NN 的数组,即要询问的摆放。也就是说,在指定的摆放中,第 a[i] 本书(0iN10\le i\le N-1)被放在位置 ii
    • 返回值为一个整数,即从指定的摆放到正确摆放,需要重复执行多少次操作。
    • 参数中,数组 a 的长度必须为 NN。如果不满足这个条件,你的程序将被判为 Wrong Answer[1]
    • 参数中,数组 a 中的每个元素都必须在 00N1N-1 之间。如果不满足这个条件,你的程序将被判为 Wrong Answer[2]
    • 参数中,数组 a 中的元素必须两两不同。如果不满足这个条件,你的程序将被判为 Wrong Answer[3]
    • 该函数最多只能被调用 50005\,000 次。如果超出调用次数,你的程序将被判为 Wrong Answer[4]
  • void answer(std::vector<int> b)
    你的程序用这个函数回答正确摆放。

    • 参数 b 为一个长度为 NN 的数组,即正确摆放。也就是说,在正确摆放中,第 b[i] 本书(0iN10\le i\le N-1)被放在位置 ii
    • 参数中,数组 b 的长度必须为 NN。如果不满足这个条件,你的程序将被判为 Wrong Answer[5]
    • 参数中,数组 b 中的每个元素都必须在 00N1N-1 之间。如果不满足这个条件,你的程序将被判为 Wrong Answer[6]
    • 参数中,数组 b 中的元素必须两两不同。如果不满足这个条件,你的程序将被判为 Wrong Answer[7]
    • 如果你回答的摆放并不是正确摆放,你的程序将被判为 Wrong Answer[8]
    • 该函数必须被调用恰好一次。如果超出调用次数,你的程序将被判为 Wrong Answer[9]。如果未调用,你的程序将被判为 Wrong Answer[10]

【注意事项】

你的程序可以定义其他函数,也可以使用全局变量。

你的程序不得使用标准输入输出流,不得以任何形式读写其他文件。但是,你的程序可以使用标准错误流来输出调试信息。

【编译运行】

可以从附件中获取 sample grader。Sample grader 即为文件 grader.cpp。将 grader.cpplibrary3.cpplibrary3.h 放置在同一目录下,运行以下命令即可编译你的程序。你也可以运行文件 compile.sh 来编译程序。

编译命令:g++ -std=gnu++20 -O2 -o grader grader.cpp library3.cpp

编译成功的话,会生成可执行文件 grader。注意,实际评测时用的 grader 与 sample grader 是不同的。Sample grader 会以单进程方式执行,从标准输入流中读取数据,输出结果到标准输出流。

*赛时公告:Sample grader 是非适应性的。实际评测时使用的 grader 是否适应是未知的。

输入格式

Sample grader 按照以下方式读取输入:

NN
B0B_0 B1B_1 \cdots BN1B_{N-1}

在正确摆放中,第 BiB_i0iN10\le i\le N-1)本书放在位置 ii 上。

输出格式

Sample grader 会输出以下结果:

  • 如果你的程序被评为正确的,返回调用 query 函数的次数。例如:Accepted: 3000
  • 否则,如果你的程序满足任一形式的错误,则按照题目描述中的错误类型输出。例如:Wrong Answer[3]

如果你的程序同时满足多种错误的条件,只会输出一种错误。

4
2 0 3 1

提示

如下是一种可能的交互过程:

调用 返回值
solve(4)
query([0, 1, 2, 3]) 3
query([1, 3, 0, 2]) 2
query([3, 0, 1, 2])
query([2, 0, 3, 1]) 0
answer([2, 0, 3, 1])

考虑调用 query([0, 1, 2, 3])。操作将会按照如下方式进行:

  • 交换第 00 本书和第 11 本书的位置。于是,第 1,0,2,31,0,2,3 本书分别被放在位置 0,1,2,30,1,2,3 上。
  • 交换第 11 本书和第 33 本书的位置。于是,第 3,0,2,13,0,2,1 本书分别被放在位置 0,1,2,30,1,2,3 上。
  • 交换第 33 本书和第 22 本书的位置。于是,第 2,0,3,12,0,3,1 本书分别被放在位置 0,1,2,30,1,2,3 上。

33 次操作后,将指定的摆放还原成了正确的摆放,所以返回值为 3

样例满足所有子任务的限制条件。

数据范围

  • 2N5002 \le N \le 500
  • 0BiN10 \le B_i \le N - 10iN10 \le i \le N - 1);
  • BiBjB_i\neq B_j0i<jN10 \le i < j \le N - 1);
  • 输入数字全为整数。

子任务

  1. 22 points)N6N \le 6
  2. 1919 points)N100N \le 100
  3. 7979 points)无额外约束。

由 Starrykiller 根据英文题面翻译。