#P11984. [JOIST 2025] 占卜 3 / Fortune Telling 3
[JOIST 2025] 占卜 3 / Fortune Telling 3
题目背景
请使用 C++ 20 提交。不要引入 anna.h
和 bruno.h
,并在代码头加入以下语句:
int DrawCard(int);
题目描述
这是一道通信题。交互库是非自适应的。
Anna 和 Bruno 在玩一种用卡牌进行的占卜游戏 次,规则如下。
-
有许多上面写着 或 的卡牌叠成一堆。Anna 从牌堆中一次抽出 () 张卡牌。Anna 和 Bruno 知道 的值。
-
每次抽到卡牌时,她会决定是弃掉这张牌还是将其放到桌上。
- 如果她选择将牌放到桌上,她会把这张牌插入桌上的卡牌序列中。
- 形式化地,当桌上有 张卡牌时,她选定非负整数 (),并将这张牌放在桌上从左数第 张卡牌右侧。
- 当 时,她将这张牌放在桌上卡牌序列的最左侧。
-
当 Anna 抽完并处理完 张卡牌后,她的操作结束。占卜结果是这 张卡牌中上面写着数字 的卡牌数量。
-
当 Anna 结束操作后,Bruno 会看到桌上的卡牌序列。基于这些信息,他需要猜出占卜结果。
如果 Bruno 猜对了,占卜就算成功。
当桌上的卡牌越少时,占卜被认为越高明。
请编写一个程序,实现 Anna 和 Bruno 的策略,使得全部 次占卜都成功。
在本题中,Anna 放在桌上的卡牌越少,得分越高。
实现细节
你不应该,也不需要实现 main
函数。
在洛谷上评测时,你只需要提交一个文件。
对于 Anna 的策略,你应该实现以下的函数:
void Anna(int N);
该函数将被调用 次。第 次调用表示第 次占卜的过程。
参数 N
()代表卡牌的数量。
每次占卜,该函数必须调用以下的函数 次:
int DrawCard(int x);
使用此函数,Anna 从牌堆中抽卡,并选择丢弃或放置在桌面上。她通过第 次调用()的返回值获取第 张卡片上的数字。她通过第 次调用()的参数指定对第 张卡片的操作。
- 第 次调用()的返回值为 或 ,表示第 张卡片上的数字。
- 特别地,第 次调用的返回值为 ,表示 Anna 已完成抽卡。
- 第 次调用的参数 必须为 ,否则程序将被判定为 。
- 第 次调用的参数 表示对第 张卡片的操作:
- 若 ,则丢弃该卡片;
- 若 ,则将卡片放置在桌面上当前最左数第 张卡片的右侧;当 时,卡片置于桌面序列的最左侧。
- 参数需满足 ( 为当前桌面卡片数),否则程序将被判定为 。
- 若调用
DrawCard
函数的次数不为 ,程序将被判定为 。
对于 Bruno 的策略,你应该实现以下的函数:
int Bruno(int N, int L, std::vector<int> C)
该函数在每次调用 Anna
函数后被调用恰好一次,总计 次。
第 次调用()对应第 次占卜流程,需返回 张卡牌中上面写着数字 的卡牌数量。
- 参数 表示 Anna 抽取的卡片总数。
- 参数 表示桌面上的卡片数量。
- 参数 为长度为 的数组,其中 表示桌面上第 张最左侧卡片()的数字。
- 若返回值不等于 张卡牌中上面写着数字 的卡牌数量,程序将被判定为 。
注意事项
- 交互库是非自适应的。
- 程序可定义其他内部函数或全局变量,但需在匿名命名空间中声明以避免冲突。
- 由于洛谷评测系统的限制,Anna 和 Bruno 将在同一进程中运行。请注意清空。
- 禁止使用标准输入输出或通过其他方式与外部文件通信,但可将调试信息输出至标准错误流。
编译与测试
下载附件中的压缩包,将以下文件置于同一目录:
- ;
- ;
- ;
- ;
- 。
运行以下命令编译:
g++ -std=gnu++20 -O2 -o grader grader.cpp Anna.cpp Bruno.cpp
或直接运行压缩包中的 :
./compile.sh
输入格式
Sample Grader 输入格式如下:
输出格式
Sample Grader 会向标准输出和标准错误流输出以下信息:
- 若程序被判定为正确,Sample Grader 将以 格式输出桌面上卡片数量的最大值。
- 若程序被判定为错误,Sample Grader 将以 格式输出错误类型。
若程序同时满足多个错误类型的条件,Sample Grader 仅报告其中一个。当检测到错误条件时,Sample Grader 可能终止执行。
2 5
0 1 0 0 1
1 1 0 1 0
Accepted: 5
提示
样例交互
样例输入包含 次占卜流程,Anna 从牌堆抽取的卡片数为 。
调用 | 返回值 | 调用 | 返回值 |
---|---|---|---|
第一次占卜流程的操作步骤如下:
- Anna 抽取第 张卡,数字为 。
- Anna 选择将卡片置于桌面最左侧,桌面序列变为 。接着抽取第 张卡,数字为 。
- Anna 选择丢弃此卡。随后抽取第 张卡,数字为 。
- Anna 选择将此卡放置在桌面上第 张最左侧卡片的右侧,桌面序列变为 。接着抽取第 张卡,数字为 。
- Anna 选择丢弃此卡。随后抽取第 张卡,数字为 。
- Anna 选择将此卡放置在桌面上第 张最左侧卡片的右侧,桌面序列变为 。
此时,Bruno 看到的桌面序列为 ,推断 Anna 抽取的卡片中数字为 的数量为 (正确)。桌面上卡片数为 。
第二次占卜流程中,桌面上卡片数为 。
注:此样例输入不满足题目约束。附件压缩包中,sample-01-in.txt
对应样例输入 1,sample-02-in.txt
为满足约束的样例输入。
数据范围
- ;
- ;
- ,。
计分方式
若程序在任何测试用例中被判定为 (见【实现细节】)、TLE、MLE 或 RE 等,则得 分。
若程序在所有测试用例中均被判定为正确,则得分由所有测试用例中所有占卜流程内调用 DrawCard
函数时参数满足 的最大次数决定。
设该次数为 ,得分规则如下:
条件 | 得分 |
---|---|
$\displaystyle \left\lfloor100 \times \left( \frac{2.5}{L - 11.5} \right)^{0.35}\right\rfloor$ | |