Anna 和 Bruno 这两位赌博专家即将与庄家 D-taro 进行一场游戏。
在游戏中,Anna 和 Bruno 被隔离在不同的房间里,只能通过庄家 D-taro 进行交流。
游戏中有一排 $N$ 盏灯。这些灯从左到右编号为 $1$ 到 $N$,每盏灯可以被点亮为红、绿、蓝三种颜色之一。
游戏开始时,Anna 将每盏灯点亮为红、绿或蓝。此外,庄家 D-taro 为每盏灯指定了一种禁止颜色,用长度为 $N$ 的字符串 $S$ 表示。令 $S_i$ 表示 $S$ 的第 $i$ 个字符($1 \le i \le N$)。如果 $S_i$ 为 'R',则灯 $i$ 的禁止颜色为红色;如果 $S_i$ 为 'G',则为绿色;如果 $S_i$ 为 'B',则为蓝色。Anna 不能将灯 $i$ 点亮为它的禁止颜色。例如,如果 $S_1$ 为 'R',Anna 就不能将灯 $1$ 点亮为红色。庄家 D-taro 将每盏灯的禁止颜色信息传达给 Anna,但不传达给 Bruno。
点亮所有灯后,Anna 选择一个满足 $1 \le l \le \min(N, 130)$ 的整数 $l$,并告知庄家 D-taro。随后,庄家 D-taro 将灯的总数 $N$ 和 Anna 选择的整数 $l$ 告知 Bruno。
接着,他们进行 $Q$ 轮游戏,流程如下:
- 庄家 D-taro 选择一个 $1$ 到 $N - l + 1$ 之间的整数 $a_j$,并向 Bruno 展示灯 $a_j, a_j + 1, \dots, a_j + l - 1$ 的颜色序列。
- Bruno 根据展示的颜色序列向庄家 D-taro 回复一个整数。如果该整数与 $a_j$ 相等,则 Anna 和 Bruno 赢得该轮。
然而,庄家 D-taro 可能会根据 Anna 点亮的颜色序列和所选的整数 $l$ 来改变 $a_1, a_2, \dots, a_Q$ 的选择。
你需要实现一个程序,使 Anna 和 Bruno 能赢得所有 $Q$ 轮游戏。
实现细节
你需要提交两个文件。
第一个文件是 Anna.cpp。它应实现 Anna 的策略,并实现以下函数。程序应使用预处理指令 #include 包含 Anna.h。
std::pair<std::string, int> anna(int N, std::string S)该函数在初始时被调用一次。- 参数 $N$ 是灯的数量。
- 参数 $S$ 是一个长度为 $N$ 的字符串,表示庄家 D-taro 指定的禁止颜色。
- 返回值是一个
pair,包含一个表示 Anna 点亮每盏灯颜色的字符串 $t$ 和一个 Anna 选择的整数 $l$。令 $t_i$ 表示 $t$ 的第 $i$ 个字符($1 \le i \le N$)。$t_i$ 表示 Anna 将第 $i$ 盏灯点亮的颜色。如果 $t_i$ 为 'R',则灯 $i$ 的颜色为红色;如果 $t_i$ 为 'G',则为绿色;如果 $t_i$ 为 'B',则为蓝色。 - 字符串 $t$ 的长度必须为 $N$。否则,将被判定为 Wrong Answer [1]。
- 字符串 $t$ 中的每个字符必须为 'R'、'G' 或 'B'。否则,将被判定为 Wrong Answer [2]。
- 字符串 $t$ 中的每个字符必须与 $S$ 中对应的字符不同。否则,将被判定为 Wrong Answer [3]。
- $l$ 必须在 $1$ 到 $\min(N, 130)$ 之间。否则,将被判定为 Wrong Answer [4]。
第二个文件是 Bruno.cpp。它应实现 Bruno 的策略,并实现以下函数。程序应使用预处理指令 #include 包含 Bruno.h。
void init(int N, int l)该函数在初始时被调用一次。- 参数 $N$ 是灯的数量。
- 参数 $l$ 是 Anna 选择的整数。
int bruno(std::string u)该函数在init函数调用后被调用 $Q$ 次,对应游戏中的第 1 步和第 2 步。- 参数 $u$ 是一个长度为 $l$ 的字符串,由 'R'、'G'、'B' 组成,表示灯 $a_j, a_j + 1, \dots, a_j + l - 1$ 的颜色序列。
- 令 $u_k$ 表示 $u$ 的第 $k$ 个字符($1 \le k \le l$)。如果 $u_k$ 为 'R',则 Anna 点亮的第 $a_j + k - 1$ 盏灯的颜色为红色;如果 $u_k$ 为 'G',则为绿色;如果 $u_k$ 为 'B',则为蓝色。
- 返回值是 Bruno 回复的整数。
- 返回值必须与 $a_j$ 相等。否则,将被判定为 Wrong Answer [5]。
重要提示
- 你的程序可以实现其他内部函数或使用全局变量。提交的文件将与评测程序一起编译,成为一个单一的可执行文件。所有全局变量和内部函数应声明在匿名命名空间中,以避免与其他文件冲突。评测时,它将作为 Anna 和 Bruno 两个进程执行。Anna 的进程和 Bruno 的进程不能共享全局变量。
- 你的程序不得使用标准输入和标准输出。你的程序不得通过任何方式与其他文件通信。但是,你的程序可以将调试信息输出到标准错误。
编译与测试
你可以从比赛网页下载包含示例评测程序的压缩包来测试你的程序。压缩包中还包含你的程序的示例源文件。
示例评测程序是 grader.cpp。为了测试你的程序,将 grader.cpp、Anna.cpp、Bruno.cpp、Anna.h、Bruno.h 放在同一目录下,并运行以下命令来编译你的程序。或者,你可以运行压缩包中包含的 compile.sh。
g++ -std=gnu++20 -O2 -o grader grader.cpp Anna.cpp Bruno.cpp
编译成功后,将生成可执行文件 grader。
注意,实际的评测程序与示例评测程序不同。示例评测程序将作为一个单一进程执行,它会从标准输入读取输入数据,并将结果写入标准输出和标准错误输出。
样例
样例 1
8 RGGBRBBG 2 3 1
样例说明
在此示例中,Anna 接收到灯的数量 $N = 8$ 和表示禁止颜色的字符串 $S = \text{"RGGBRBBG"}$。Anna 选择将每盏灯点亮为字符串 $t = \text{"BBRGBGRR"}$,并选择整数 $l = 5$,将其传达给庄家 D-taro。然后,庄家 D-taro 将 $N = 8$ 和 $l = 5$ 告知 Bruno。
在第一轮中,庄家 D-taro 选择 $a_1 = 3$。Bruno 接收到灯 $3, 4, 5, 6, 7$ 的颜色序列,由字符串 $u = \text{"RGBGR"}$ 表示,并回复整数 $3$,这与 $a_1$ 相符。
输入样例 1 满足所有子任务的约束。比赛网站上可下载的文件 sample-01-in.txt 对应于输入样例 1。
数据范围
- $1 \le N \le 500\,000$
- $1 \le Q \le 10\,000$
- $S$ 是一个长度为 $N$ 的字符串,由 'R'、'G' 或 'B' 组成。
- $N$ 和 $Q$ 为整数。
子任务
- (5 分) $N \le 131$
- (5 分) $N \le 250$
- (5 分) $N \le 380$
- (15 分) $N \le 7\,000$
- (70 分) 无附加约束。在此子任务中,得分判定如下:
- 令 $l^*$ 表示 Anna 在该子任务的所有测试用例中选择的 $l$ 的最大值。
- 如果该子任务中的任何测试用例被判定为 Wrong Answer [1] ~ [5](见实现细节),或超过时间限制、内存限制,或遇到运行时错误,则该子任务得分为 0 分。
- 如果该子任务中的所有测试用例均正确,则子任务得分判定如下:
| $l^*$ 的值 | 得分 |
|---|---|
| $61 < l^* \le 130$ | 10 分 |
| $41 < l^* \le 61$ | 20 分 |
| $34 < l^* \le 41$ | $25 + 3 \times (41 - l^*)$ 分 |
| $28 < l^* \le 34$ | $46 + 4 \times (34 - l^*)$ 分 |
| $l^* \le 28$ | 70 分 |