Byteasar 热衷于收集 Bytémon 卡片。他牌堆中的每张卡片都印有一只 Bytémon 的图片及其目录编号,编号为 $[1, 2 \cdot 10^9]$ 范围内的整数。到目前为止,Byteasar 还没有收集齐所有的 Bytémon。事实上,他的收藏很特别:每种 Bytémon 都有多张卡片,且每种 Bytémon 的卡片数量相同。
有一天,Byteasar 发现有人从他的收藏中偷走了一些(即一张或多张)卡片。他知道所有被偷走的卡片都是一样的,即印有同一种 Bytémon。幸运的是,他的收藏中至少还剩下一张该种类的卡片。不幸的是,我们的英雄记性很差,已经忘记了是哪种 Bytémon。你能通过提醒他丢失了哪些卡片来帮助他吗?请注意,你的程序必须符合严格的内存限制。
编写一个程序,通过与一个库进行交互来遍历 Byteasar 的卡片牌堆,从而确定被偷走的 Bytémon 的目录编号。
交互
要使用该库,你需要在程序开头包含以下内容:
#include "ckollib.h"
该库提供了以下函数和过程:
int karta();返回 $[1, 2 \cdot 10^9]$ 范围内的整数或 0。返回 0 表示牌堆结束,返回正整数则表示下一张卡片上 Bytémon 的目录编号。在收到 0 后,你的程序仍然可以调用karta函数,这对应于对牌堆的另一次遍历。在每次遍历中,Bytémon 的目录编号给出的顺序相同。void odpowiedz(int wynik);告诉库wynik是被偷走的 Bytémon 的目录编号。调用此函数将终止你的程序。
你的程序不能从标准输入读取任何数据,也不能从任何文件中读取。同样,它也不能向标准输出或任何文件写入任何内容。它可以向标准错误(stderr)写入内容,但请记住这会消耗宝贵的时间。
子任务
对于任何测试,评分规则如下:
- 如果你的程序最多进行一次遍历,即在
karta第一次返回 0 后不再调用它,你将获得满分。 - 如果你的程序开始了第二次遍历,你将只能获得 40% 的分数。
- 如果你的程序开始了第三次遍历,它将被库终止,且不会获得任何分数。
牌堆中最多有 $60\,000\,000$ 张卡片。此外,在占总分 20% 的测试中,牌堆中的卡片不超过 $200\,000$ 张。
样例
样例程序执行
| C/C++ | 结果 | 说明 |
|---|---|---|
k = karta(); |
13 | 第一张卡片上 Bytémon 的目录编号。 |
k = karta(); |
13 | |
k = karta(); |
39 | |
k = karta(); |
26 | |
k = karta(); |
26 | |
k = karta(); |
0 | 牌堆结束。 |
k = karta(); |
13 | 重新遍历牌堆;卡片顺序与之前相同。 |
odpowiedz(39); |
给出答案。程序终止。 |
上述程序执行是正确的,因为它进行的遍历次数不超过两次,并返回了正确的值。然而,由于它开始了第二次遍历,因此只能获得 40% 的分数。要获得满分,程序必须仅进行一次遍历。
实现细节
在目录 dlazaw 中,有一个示例库可以让你测试解决方案的正确性。该库从标准输入读取牌堆描述,格式如下:
- 第一行包含一个正整数 $n$ —— 牌堆中的卡片数量。
- 第二行包含 $n$ 个 $[1, 2 \cdot 10^9]$ 范围内的正整数 —— 牌堆中连续卡片上的 Bytémon 编号。
示例库不会检查牌堆中是否确实只有一种 Bytémon 的卡片数量少于其他任何 Bytémon。
该库的示例输入可以在文件 kol0.in 中找到。在调用 odpowiedz 过程后,库会向标准输出打印有关给定答案、karta 函数调用次数以及遍历次数的信息。
在同一目录下,有示例解决方案 kol.c 和 kol.cpp,它们利用了该库。这些解决方案是不正确的,因为它们总是回答 Byteasar 寻找的编号是牌堆中最后一张卡片上的编号。
要将你的解决方案与库一起编译,请使用以下命令:
- C:
gcc -O2 -static ckollib.c kol.c -lm - C++:
g++ -O2 -static ckollib.c kol.cpp -lm -std=gnu++0x
包含你的解决方案的文件和库文件应放置在同一目录下。