P7135 小 B 的面包
题目背景
本题是一道**函数式交互题**。
小 B 获得了很多面包,小 Y 很愤怒,他想抢夺面包。
小 Y 提出要和小 B 玩一个有趣的游戏,如果小 B 输了,小 B 就要被抢走所有面包。
小 B 还要到【数据删除】江边散步,所以他把这个任务交给了你。
聪明的你能帮小 B 守卫他宝贵的面包吗?
题目描述
**本题建议使用 `c++` 语言编程**。
小 Y 把 $9$ 个面包依次放在了桌子上,第 $i$ 个面包的质量为 $i$。
小 Y 与你轮流选取面包,谁选取的面包中,任意三个面包的总质量先恰好达到 $15$,谁就获胜,另外一方则落败。**每个面包只能取一次,一个人取了某个面包后另一个人就不能再选取了,选取面包后不能再放回**。
如果最后面包全部选取完后双方未均达到,则为平局。
---
本题中,你需要且只需要实现以下三个函数(可以在其中调用或访问你的自写函数或全局变量):
```cpp
extern "C" int choose(int x);
extern "C" void init();
extern "C" void newgame(bool f);
/* 注意以上三个函数之前的 extern "C" 不可省略 */
```
评测时,交互库将首先调用一次你所实现的 `init()` 函数。`init()` 函数的作用为方便你最开始初始化,之后不会再次调用,如果你不需要初始化也请加入 `extern "C" void init() {}`。
接下来交互库会调用你所实现的 `newgame(bool f)` 函数,交互库调用 `newgame(bool f)` 函数表示开始一场新游戏,传入的 `f` 若等于 $1$ 表示是由交互库先选择,否则由你先选择。
接下来交互库将会不断调用你实现的 `choose(int x)` 函数,传入的 $x$ 表示小 Y 选取了第 $x$ 个面包,此函数运行结束后你需要返回一个整数 $y(1 \le y \le 9)$,表示你选取了第 $y$ 个面包,即:
```cpp
extern "C" int choose(int x) { /*x为交互库选取的面包 */
/* 你的代码 */
return y; /* y为你选取的面包 */
}
```
特别地,当传入的 $x=0$ 时,表示是由你先选取面包。如果你 `choose(int x)` 函数返回了不合法的值,该场游戏立即结束,且结果为交互库获胜。
不停调用 `choose(int x)` 函数直到某一方胜利或平局,即该场游戏结束。接着,交互库又会调用 `newgame(bool f)` 函数,开始一场新游戏。交互库一共会调用 $1800$ 次 `newgame(bool f)` 函数,表示进行 $1800$ 场游戏。
详细可查看`template_game.cpp`。
---
在附加文件中,有以下一个文件:
`template_game.cpp`——你将在其中实现上述三个函数,内含详细注释,也包括交互库参考代码,请仔细阅读,**建议在此基础上答题**。
本地可直接在 IDE 中编译。
输入格式
无
输出格式
对于本地交互库,**交互库**最后会输出两行:
第一行两个数 $w,d$ ,分别表示你获胜的场数和平局的场数;
第二行为你的得分。
说明/提示
**保证交互库采用完全随机选取策略,即每次均会从未选取的面包中等概率选取一个面包**
$1800$ 场游戏中,有 $600$ 场是由你的程序先选取,有 $1200$ 场是由交互库先选取。
具体来说,对于第 $i$ 场游戏,若 $i \bmod 3 =0$ ,则由你的程序先选取,否则由交互库先选取。
本题首先会受到和传统题相同的限制,例如编译错误会导致整道题目得 $0$ 分,运行时错误、超过时间限制、超过空间限制等会导致相应测试点得 $0$ 分等。
你只能访问自己定义的和交互库给出的变量及其对应的内存空间,尝试访问其他空间将可能导致编译错误或运行错误。
**本题只有一个测试点,你的得分按如下规定判定:**
设你程序获胜了 $x$ 场,平局为 $y$ 场,你最终的得分用计分函数 $f(x,y)$ 表示为:
$$
f(x,y)=\lfloor (\frac{x+y}{6}-200) \cdot \min((\frac{x}{x + y})^2+0.2,1) \rfloor
$$
最低得分为 $0$ 分。
**实际评测的交互库与下发的不相同,选手的程序应不依赖于交互库实现**。
详细可查看`template_game.cpp`。