题目描述
请注意,在 LibreOJ 上,本题暂时只支持 C / C++ 语言提交。
题目译自 JOISC 2016 Day1 T2 「神経衰弱」
现有 2N 张纸牌,每张纸牌上都写着一个 0 以上 N−1 以下的整数,写着同样整数的纸牌有且只有两张。你和 JOI 君正利用这 2N 张纸牌练习一个叫做神经衰弱的游戏。
游戏开始时,这些纸牌正面向下,从左到右依次摆放。左起第 i+1 (0≤i≤2N−1) 张牌称为纸牌 i。令 Ai (0≤i≤2N−1) 为纸牌 i 上写的数字。最初,你和 JOI 君都不知道 Ai 的值是什么。
你和 JOI 君可以最多进行 K 次以下问答:
- 你先选定 2N 张牌中的两张;
- JOI 君翻开这两张你指定的牌,看它们上面写的数字,但是你看不到这个过程。如果这两张牌上写的数字相同,他会记住这个数值并告诉你。否则,他会记住两个数字中更好记的一个,并告诉你更好记的那个数。
JOI 君对整数的记忆力可以用 N 个整数 P0,P1,…,PN−1 表达。这些整数满足以下条件:
- 0≤Pi≤N−1 (0≤i≤N−1)
- Pi=Pj (0≤i<j≤N−1)
JOI 君认为整数 i 比 j 好记,当且仅当 Pi<Pj。
你的任务是在最多进行 K 次问答的情况下确定每张牌上写的数字。但你不知道代表 JOI 君记忆力的整数 P0,P1,…,PN−1 的值。
请和 JOI 君配合,写一个程序确定每张牌上写的数字。
实现细节
你需要写一个程序实现确定每张牌上写的数字的功能。你的程序需要引入 Memory2_lib.h
库。
程序中必需实现以下函数:
- void Solve(int T, int N)
对于每组测试数据,这个函数仅调用一次。T 代表子任务编号,N 代表有 2N 张牌。
这个函数必需通过调用 Flip 函数来确定牌上写的数字,通过调用 Answer 函数来做出回答。
程序中可以调用以下函数:
-
int Flip(int I, int J)
当指定 JOI 君翻哪两张牌时调用这个函数。参数 I, J 表示 JOI 君需要翻开纸牌 I 和 J。
I 和 J 都必须是 0 到 2N−1(包括两端)的整数,并且 I 不等于 J。如果调用 Flip 函数时不满足条件,则会被判为 Wrong answer [1]。
如果 AI=AJ,则这个函数返回这个值,否则会返回 AI 和 AJ 中更容易记住的那个值。
如果这个函数调用超过 K 次,则会被判为 Wrong answer [2]。
-
void Answer(int I, int J, int X)
这个函数表示写有整数 X 的卡片可以被确定了。
参数 I, J, X 需要满足以下条件:
- 0≤I,J≤2N−1
- I=J
- AI=AJ=X
如果调用时参数不满足以上条件,则会被判为 Wrong answer [3]。
调用时,参数 X 的值需要与先前任意调用中的 X 不同。如果不满足,则会被判为 Wrong answer [4]。
此函数必须恰好被调用 N 次,否则会被判为 Wrong answer [5]。
你的程序可以实现任何其他函数,或定义全局变量。但你的程序无论如何都不可以与标准输入输出或其他文件交互。
如何编译运行
附加文件中包含一个样例交互器和交互库,仅用作测试。
样例交互器包含一个文件,文件名为 grader.c
或 grader.cpp
。为了测试程序,需执行如下命令:
gcc -std=c11 -O2 -o grader grader.c dungeon2.c -lm
g++ -std=c++11 -O2 -o grader grader.cpp dungeon2.cpp
如果编译成功,则会生成一个名为 grader
的可执行文件。
请注意,实际判题过程和样例的判题过程不同。样例判题程序作为单进程执行。这个程序需要从标准输入中读入,并输出到标准输出中。
样例交互程序输入
第一行三个整数 T,N,K,由一个空格隔开。分别表示子任务编号为 T,有 2N 张牌,和 JOI 君最多问答 K 次。
第二行 N 个整数 P0,P1,…,PN−1,表示 JOI 君对整数的记忆力。
第三行 2N 个整数 A0,A1,…,A2N−1,表示从左到右纸牌上写的整数。
样例交互程序输出
如果样例交互程序正常退出,它会向标准输出输出一行如下内容:
- 如果答案正确,输出
Accepted
。
- 如果不正确,输出错误的类型,如
Wrong answer [2]
。
数据范围
对于所有输入,满足以下条件:
- 1≤N≤50
- 0≤Pi≤N−1 (0≤i≤N−1)
- Pi=Pj (0≤i<j≤N−1)
- 0≤Ai≤N−1 (0≤i≤2N−1)
- 对于所有整数 x (0≤x≤N−1),满足 Ai=x (0≤i≤2N−1) 的 i 有且只有两个。
详细子任务附加条件及分值如下表所示。
子任务编号 |
附加条件 |
分值 |
1 |
T=1,K=10 000,Pi=i (0≤i≤N−1) |
10 |
2 |
T=2,K=400,Pi=i (0≤i≤N−1) |
50 |
3 |
T=3,K=300 |
40 |
样例交互过程
输入为
1 3 10000
0 1 2
1 0 2 0 1 2
样例交互过程如下
函数调用 |
返回值 |
Flip(0, 2) |
1 |
Flip(0, 4) |
1 |
Flip(1, 2) |
0 |
Answer(0, 4, 1) |
|
Flip(1, 3) |
0 |
Flip(5, 2) |
2 |
Flip(4, 5) |
1 |
Answer(1, 3, 0) |
|
Answer(5, 2, 2) |
|