你是否听说过 Just Ordinary Inventions 公司?这家公司的业务是进行“只是平凡的发明(just ordinary inventions)”。
JOI 君正在游玩一款由 Just Ordinary Inventions 公司开发的最新游戏。这个游戏是一款探索地下城的游戏,地下城由若干房间和若干道路组成。道路连接地下城中两个不同的房间,并且可以双向通行。任意两个不同的房间之间,至多只有一条道路相连,并且不存在起点和终点是同一个房间的道路。同时,可以确定的是,地下城中任意两个房间之间,都可以通过若干条道路相互到达。
各个房间彼此非常相似,仅通过观察房间的外观,完全无法区分那些“伸出道路数量相同”的房间。
为了帮助攻略游戏,每个房间中都设置了一个标记和一个台座。以标记为基准,从房间中伸出的道路可以编号为第 $1$ 条、第 $2$ 条,……。在游戏过程中,地下城的结构不会发生变化。因此,从同一个房间出发,选择同一个编号的道路移动,始终会到达同一个房间。
台座上摆放着一颗宝石,玩家可以改变它的颜色。宝石的颜色可能是颜色 $1, 2, \ldots, X$ 中的一种。游戏开始时,所有房间中的宝石颜色均为颜色 $1$。除非玩家进行操作,宝石的颜色不会发生变化。
JOI 君意识到,如果能够知道地下城的结构,也就是房间之间是如何通过道路连接的,那么这个游戏就可以轻松攻略。然而,无论 JOI 君如何尝试,都无法确定地下城的结构。于是,你决定代替 JOI 君,编写一个用于确定地下城结构的程序。
任务说明
请编写一个程序,通过探索地下城来确定地下城的结构。不过,JOI 君并不希望地下城的结构被完全揭示出来,因此程序不能直接输出地下城的结构,而是需要回答如下问题:
对于每个整数 $i$($1 \le i \le R$),回答“最少恰好使用 $i$ 条道路即可相互到达的两间房间的组合有多少个”。交换房间顺序视为同一组合。
为了探索地下城,你可以使用以下由库提供的操作:
- 获取当前所在房间中伸出的道路数量。
- 获取当前所在房间台座上宝石的颜色。
- 将当前所在房间台座上宝石的颜色设置为指定的颜色(也可以指定为当前颜色),然后选择一条道路并沿该道路移动到另一个房间。
- 获取最后一次使用的道路是当前房间中伸出的第几条道路。
实现细节
你需要编写一个程序来实现向 JOI 君回答的方式。程序必须包含头文件 dungeon2.h。
程序需要实现以下例程:
Inspect
void Inspect(int R)
- 该例程只会被调用一次。
- 参数
R表示你需要对每个整数 $i$($1 \le i \le R$),回答“最少恰好使用 $i$ 条道路即可相互到达的两间房间的组合数量”。
在该例程中,你需要调用下面的例程来回答问题。
Answer
void Answer(int D, int A)
- 参数
D, A表示:最少恰好使用 $D$ 条道路即可相互到达的两间房间的组合数量为 $A$。
调用 Answer 时必须满足以下条件:
- $D$ 必须是 $1$ 到 $R$ 之间的整数。否则判为不正确 [1]。
- 不得对同一个 $D$ 调用
Answer两次或以上。否则判为不正确 [2]。 Answer必须被调用恰好 $R$ 次。否则判为不正确 [3]。- $A$ 必须是正确的组合数量。否则判为不正确 [4]。
一旦某次 Answer 调用被判定为不正确,之后程序是否继续执行将不作保证。
此外,在程序中你还可以调用以下例程:
Move
void Move(int I, int C)
- 参数
I表示选择用于移动的道路编号。调用后,玩家将沿当前房间中第 $I$ 条道路移动到另一个房间。 - 参数
C表示在移动之前,将当前房间台座上的宝石颜色设置为颜色 $C$。
调用 Move 时必须满足:
- 设当前房间中伸出的道路数为 $K$,则 $I$ 必须满足 $1 \le I \le K$。否则判为不正确 [5]。
- 设宝石颜色总数为 $X$,则 $C$ 必须满足 $1 \le C \le X$。$X$ 的值由子任务确定。否则判为不正确 [6]。
Move的调用次数不得超过 $1\,500\,000$ 次。否则判为不正确 [7]。
NumberOfRoads
int NumberOfRoads()
- 返回当前所在房间中伸出的道路数量。
LastRoad
int LastRoad()
- 返回最后一次使用的道路在当前房间中是第几条道路。
- 若在未调用过
Move之前调用该函数,则返回 $-1$。
Color
int Color()
- 返回当前所在房间台座上宝石的颜色。
当 Inspect 调用结束后,将进行答案判定。
你可以自由实现其他内部使用的例程,或声明全局变量。但你的提交不得通过标准输入、标准输出或任何文件与外界进行交互。
编译与运行方式
用于测试你程序的评测程序样例包含在竞赛网站提供的下载压缩包中,其中也包含你需要提交的文件样例。
评测程序样例由一个文件组成,文件名为 grader.c 或 grader.cpp。测试方法如下:
- C 语言 ```
gcc -std=c11 -O2 -o grader grader.c dungeon2.c -lm
- **C++**
g++ -std=c++11 -O2 -o grader grader.cpp dungeon2.cpp
若编译成功,将生成名为 `grader` 的可执行文件。
请注意,实际使用的评测程序与样例评测程序不同。样例评测程序作为单一进程运行,从标准输入读取数据,并向标准输出写入结果。
### 输入格式(评测程序样例)
评测程序样例从标准输入读取以下数据:
- 第 $1$ 行包含三个整数 $N, X, R$,表示地下城中有 $N$ 个房间(房间 $1$ 到房间 $N$),宝石颜色有 $X$ 种,需要回答的值有 $R$ 个。
- 接下来的 $2N$ 行中:
- 第 $2i-1$ 行($1 \le i \le N$)包含整数 $D_i$,表示房间 $i$ 中伸出的道路数量。
- 第 $2i$ 行包含 $D_i$ 个整数 $T_{i1}, T_{i2}, \ldots, T_{iD_i}$,表示从房间 $i$ 出发,沿第 $j$ 条道路会到达房间 $T_{ij}$。
- 接下来的 $R$ 行中,第 $j$ 行($1 \le j \le R$)包含整数 $A_j$,表示最少恰好使用 $j$ 条道路即可相互到达的两间房间的组合数量。
也就是说,若对每个 $j$ 调用 `Answer(j, A_j)`,评测程序样例将判定为正确,否则判定为不正确。
评测程序样例将玩家的初始位置设为房间 $1$,然后调用你实现的例程。
### 输出格式(评测程序样例)
若程序正常结束,评测程序样例将在标准输出中输出一行信息:
- 若正确,输出类似Accepted : #move = 8
表示 `Move` 的调用次数。 - 若不正确,输出类似
Wrong Answer [1]
### 限制
所有输入数据满足以下条件($N, D_i, T_{ij}$ 的含义见上文):
- $2 \le N \le 200$
- $3 \le X \le 100$
- $1 \le R \le 200$
- $1 \le D_i \le N-1$($1 \le i \le N$)
- $1 \le T_{ij} \le N$ 且 $T_{ij} \ne i$
- $T_{i1}, T_{i2}, \ldots, T_{iD_i}$ 两两不同
- 对任意 $i, j$,存在 $k$ 使得 $T_{T_{ij},k} = i$
- 任意两个房间之间都可以通过若干条道路相互到达
### 子任务
设地下城中的房间数为 $N$,道路数为 $M$。
#### 子任务 1(17 分)
- $N \le 50$
- $M \le 100$
- $X = 100$
#### 子任务 2(27 分)
- $N \le 50$
- $M \le 100$
- $X = 3$
#### 子任务 3(56 分)
- $X = 3$
该子任务的得分方式如下:
- 设在该子任务的所有测试数据中,以下值的最大值为 $L$:
- 若 `Move` 的调用次数为 $C$,则取 $\frac{C}{M}$。
- 得分规则:
- $L \le 14$:56 分
- $14 < L \le 32$:$\lfloor 70 - L \rfloor$ 分
- $32 < L \le 64$:$\left\lfloor 54 - \frac{L}{2} \right\rfloor$ 分
- $64 < L$:0 分
其中,$\lfloor x \rfloor$ 表示不超过 $x$ 的最大整数。
在评测系统中,只要程序正确结束并被判定为正确,详细信息栏将显示 `Accepted`。但在子任务 3 中,若存在测试数据使得 $\frac{C}{M} > 64$,结果栏将显示为不正确,请特别注意。
### 交互示例
下面给出评测程序样例读取的输入示例,以及对应的例程调用示例。
**输入示例**4 3 3 1 2 3 1 3 4 2 2 4 2 2 3 4 2 0
```
例程调用示例
| 调用 | 返回值 |
|---|---|
| Inspect(3) | |
| NumberOfRoads() | 1 |
| LastRoad() | -1 |
| Move(1, 2) | |
| Color() | 1 |
| LastRoad() | 1 |
| NumberOfRoads() | 3 |
| Move(1, 3) | |
| Color() | 2 |
| Answer(1, 4) | |
| Answer(2, 2) | |
| Answer(3, 0) |
请注意,该示例中的函数调用不一定是有意义的调用。