#HK5015. 「POI2013 R3」第一名在哪里? Where is number one?
「POI2013 R3」第一名在哪里? Where is number one?
题目描述
题目译自 XX Olimpiada Informatyczna — III etap Gdzie jest jedynka?
Bajtazar 构思了一个从 到 的排列 ,并希望你猜出数字 在排列中的位置。为了避免你盲目猜测,他会回答以下两种问题:
- :排列 的第 个元素与第 个元素的差是否能被 整除,即 ?
- :排列 的第 个元素是否大于第 个元素?
其中, 为集合 中的任意索引, 为任意正整数。
在猜谜游戏中,你可无限制使用 类型问题,但需尽量减少 类型问题的数量。请编写一个程序,与 Bajtazar 提供的库交互,解决这个谜题。
交互方式
程序需在开头引入库:
- C/C++:
#include "cgdzlib.h" - Pascal:
uses pgdzlib;
库提供以下函数:
inicjuj:返回 ,需在程序开始时调用一次。- C/C++:
int inicjuj(); - Pascal:
function inicjuj: LongInt;
- C/C++:
f(i, j, d):向库询问 类型问题,若 返回 ,否则返回 。- C/C++:
int f(int i, int j, int d); - Pascal:
function f(i, j, d: LongInt): LongInt;
- C/C++:
g(i, j):向库询问 类型问题,若 返回 ,否则返回 。- C/C++:
int g(int i, int j); - Pascal:
function g(i, j: LongInt): LongInt;
- C/C++:
odpowiedz(k):告知库 位于排列的第 位(即 ),调用后程序终止。- C/C++:
void odpowiedz(int k); - Pascal:
procedure odpowiedz(k: LongInt);
- C/C++:
你的程序不得读取任何数据(包括标准输入或文件),不得向文件或标准输出写入内容。可向标准错误输出(stderr)写入诊断信息,但这会消耗时间。
编译与运行
在「文件」中,提供示例库以测试程序的格式正确性。库从标准输入读取排列描述,格式如下:
- 第一行包含一个整数 ,表示排列长度;
- 第二行包含 个空格分隔的整数,从 到 ,表示排列元素。
示例输入文件 gdz0.in 包含于该目录。程序运行结束后,库将输出到标准输出,说明你的回答是否正确及使用的 类型问题数量。
同目录下提供示例代码 gdz.c、gdz.cpp 和 gdz.pas,使用该库,但未最小化 类型问题数量。
编译程序与库的命令如下:
- C:
gcc -O2 -static cgdzlib.c gdz.c -lm -o gdz - C++:
g++ -O2 -static cgdzlib.c gdz.cpp -lm -o gdz - Pascal:
ppc386 -O2 -XS -Xt gdz.pas
代码文件和库需位于同一目录。
样例
以下表格展示了一个与 Bajtazar 库交互的样例,成功找到 的位置:
| 问题编号 | 调用 | 结果 | 说明 |
|---|---|---|---|
| - | inicjuj |
||
f(1, 2, 2) |
|||
g(1, 2) |
|||
f(3, 2, 3) |
|||
g(2, 5) |
|||
f(1, 3, 2) |
|||
f(1, 4, 3) |
|||
| - | odpowiedz(4) |
- | 回答 |
在第二个问题后,我们知道 。因此,第三个问题表明可能有: 或 或 。第四个问题排除第一种可能。第五个问题表明 。由于第六个问题确认 ,故 ,。因此, 位于位置 。
此问题序列正确找到 的位置,但不会得分,因为对于 的任意排列,,而示例使用了两个 类型问题。 类型问题数量不影响评分。
数据范围与提示
设 为在长度为 的任意排列中找到 的位置所需的最少 类型问题数量。你的程序仅当使用的 类型问题数量不超过 时,才能在该测试数据上得分。此外,程序需满足时间限制,因此 类型问题的数量应合理(但无需最小化)。
对于 的测试数据,。
所有测试数据满足 。