经过数百年的岁月,JOI 市变成了一座废墟。探险家 IOI-chan 正在探索图书馆的遗址。根据探索结果,已知以下信息:
- 图书馆的书架上曾有 $N$ 本书。这 $N$ 本书在书架上从左到右排成一行。
- 这 $N$ 本书的编号从 $1$ 到 $N$。但是,书架上书的顺序可能与书的编号顺序不同。
- 通过一次操作,可以一次性取走书架上连续放置的书。
不幸的是,IOI-chan 在图书馆里找不到旧书了。但她发现了一台管理图书馆书架操作的机器。如果我们指定一本或多本图书的编号并向机器发送查询,它会回答仅取走这些书所需的最少操作次数。
IOI-chan 想通过向机器发送查询来了解书架上书的顺序。然而,由于如果 $N$ 本书的顺序颠倒,机器的回答也是一样的,因此她不需要指定书是从左到右放置还是从右到左放置。
由于机器很旧,她最多只能向机器发送 $20\,000$ 次查询。
任务
编写一个程序,通过向机器发送最多 $20\,000$ 次查询来确定书架上书的顺序。不需要指定书是从左到右放置还是从右到左放置。
实现细节
你需要提交一个文件。
文件名应为 library.cpp。它应该实现以下函数。程序应包含 library.h。
void Solve(int N)对于每个测试用例,该函数会被调用一次。- 参数 $N$ 是书架上书的数量 $N$。
你的程序可以调用以下函数:
int Query(const std::vector<int>& M)如果指定了一本或多本图书的编号,该函数将返回仅取走这些书所需的最少操作次数。- 从书架上取走的书由参数 $M$ 指定,这是一个大小为 $N$ 的向量。对于每个 $i$ ($1 \le i \le N$),如果 $M[i-1] = 0$,则书 $i$ 不会从书架上取走。如果 $M[i-1] = 1$,则书 $i$ 会从书架上取走。如果 $M$ 的大小与 $N$ 不同,你的程序将被判定为 Wrong Answer [1]。对于每个 $i$,$M[i-1]$ 应等于 $0$ 或 $1$。至少应存在一个 $i$ ($1 \le i \le N$) 使得 $M[i-1] = 1$。如果这两个条件中至少有一个未满足,你的程序将被判定为 Wrong Answer [2]。如果
Query函数被调用超过 $20\,000$ 次,你的程序将被判定为 Wrong Answer [3]。
- 从书架上取走的书由参数 $M$ 指定,这是一个大小为 $N$ 的向量。对于每个 $i$ ($1 \le i \le N$),如果 $M[i-1] = 0$,则书 $i$ 不会从书架上取走。如果 $M[i-1] = 1$,则书 $i$ 会从书架上取走。如果 $M$ 的大小与 $N$ 不同,你的程序将被判定为 Wrong Answer [1]。对于每个 $i$,$M[i-1]$ 应等于 $0$ 或 $1$。至少应存在一个 $i$ ($1 \le i \le N$) 使得 $M[i-1] = 1$。如果这两个条件中至少有一个未满足,你的程序将被判定为 Wrong Answer [2]。如果
void Answer(const std::vector<int>& res)使用此函数,你的程序回答书架上书的顺序。不需要指定书是从左到右放置还是从右到左放置。- 参数 $res$ 是一个大小为 $N$ 的向量。它描述了书架上书的顺序。对于每个 $i$ ($1 \le i \le N$),书架上从左往右数第 $i$ 本书的编号为 $res[i-1]$。如果 $res$ 的大小与 $N$ 不同,你的程序将被判定为 Wrong Answer [4]。$res[i-1]$ 应为 $1$ 到 $N$ 之间的整数(包含 $1$ 和 $N$)。如果此条件未满足,你的程序将被判定为 Wrong Answer [5]。此外,整数 $res[0], res[1], \dots, res[N-1]$ 应互不相同。如果此条件未满足,你的程序将被判定为 Wrong Answer [6]。
当 Solve 函数终止时,如果调用 Answer 函数的次数不为 $1$,你的程序将被判定为 Wrong Answer [7]。
如果 Solve 函数指定的书的顺序与书架上书的实际顺序不同,你的程序将被判定为 Wrong Answer [8]。不需要指定书是从左到右放置还是从右到左放置。
重要事项
- 你的程序可以实现其他内部使用的函数,或使用全局变量。
- 你的程序不应使用标准输入和标准输出。你的程序不应通过任何方式与其他文件通信。但是,你的程序可以将调试信息输出到标准错误。
编译与测试运行
你可以从竞赛网页下载包含样例评测程序的压缩包来测试你的程序。该压缩包还包含你的程序的样例源文件。
样例评测程序由一个源文件 grader.cpp 组成。如果你的程序是 library.cpp,为了测试它们,请将这些文件(grader.cpp, library.cpp)和 library.h 放在同一个目录下,并运行以下命令来编译你的程序:
g++ -std=c++14 -O2 -o grader grader.cpp library.cpp
当编译成功后,会生成可执行文件 grader。
注意,实际的评测程序与样例评测程序不同。样例评测程序将作为一个单独的进程执行,它会从标准输入读取输入数据并将结果写入标准输出。
样例评测程序的输入格式
样例评测程序从标准输入读取以下数据:
- 第一行包含整数 $N$,即书架上书的数量。
- 接下来的 $N$ 行中,第 $i$ 行 ($1 \le i \le N$) 包含整数 $A_i$。这意味着从左往右数第 $i$ 本书的编号为 $A_i$。
样例评测程序的输出格式
当程序成功终止时,样例评测程序会将以下信息写入标准输出。(引号不包含在实际输出中。)
- 如果你的程序被判定为正确,样例评测程序会以以下形式写入
Query函数的调用次数:“Accepted : 100.” - 如果你的程序被判定为 Wrong Answer,样例评测程序会以以下形式写入其类型:“Wrong Answer [1].”
如果你的程序被判定为多种类型的 Wrong Answer,样例评测程序仅报告其中一种。
约束
所有输入数据满足以下条件。关于 $N$ 和 $A_i$ 的含义,请参阅“样例评测程序的输入格式”。
- $1 \le N \le 1\,000$。
- $1 \le A_i \le N$ ($1 \le i \le N$)。
- $A_i \neq A_j$ ($1 \le i < j \le N$)。
子任务
共有 2 个子任务。每个子任务的分数和附加限制如下:
子任务 1 [19 分]
- $N \le 200$。
子任务 2 [81 分]
- 没有附加限制。
样例
样例输入 1
5 4 2 5 3 1
样例调用
Solve(5)
Query({1, 1, 1, 0, 0}) -> 2
Answer({4, 2, 5, 3, 1})说明
在此任务中,不需要指定书是从左到右放置还是从右到左放置。因此,如果你的程序调用 Answer({1, 3, 5, 2, 4})(其参数与上述顺序相反),你的程序也将被视为正确。