#P7135. 小 B 的面包

小 B 的面包

题目背景

本题是一道函数式交互题

小 B 获得了很多面包,小 Y 很愤怒,他想抢夺面包。

小 Y 提出要和小 B 玩一个有趣的游戏,如果小 B 输了,小 B 就要被抢走所有面包。

小 B 还要到【数据删除】江边散步,所以他把这个任务交给了你。

聪明的你能帮小 B 守卫他宝贵的面包吗?

题目描述

本题建议使用 c++ 语言编程

小 Y 把 99 个面包依次放在了桌子上,第 ii 个面包的质量为 ii

小 Y 与你轮流选取面包,谁选取的面包中,任意三个面包的总质量先恰好达到 1515,谁就获胜,另外一方则落败。每个面包只能取一次,一个人取了某个面包后另一个人就不能再选取了,选取面包后不能再放回

如果最后面包全部选取完后双方未均达到,则为平局。


本题中,你需要且只需要实现以下三个函数(可以在其中调用或访问你的自写函数或全局变量):

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 若等于 11 表示是由交互库先选择,否则由你先选择。

接下来交互库将会不断调用你实现的 choose(int x) 函数,传入的 xx 表示小 Y 选取了第 xx 个面包,此函数运行结束后你需要返回一个整数 y(1y9)y(1 \le y \le 9),表示你选取了第 yy 个面包,即:

extern "C" int choose(int x) { /*x为交互库选取的面包 */
    /* 你的代码 */
    return y; /* y为你选取的面包 */
}

特别地,当传入的 x=0x=0 时,表示是由你先选取面包。如果你 choose(int x) 函数返回了不合法的值,该场游戏立即结束,且结果为交互库获胜。

不停调用 choose(int x) 函数直到某一方胜利或平局,即该场游戏结束。接着,交互库又会调用 newgame(bool f) 函数,开始一场新游戏。交互库一共会调用 18001800newgame(bool f) 函数,表示进行 18001800 场游戏。

详细可查看template_game.cpp


在附加文件中,有以下一个文件:

template_game.cpp——你将在其中实现上述三个函数,内含详细注释,也包括交互库参考代码,请仔细阅读,建议在此基础上答题

本地可直接在 IDE 中编译。

输入格式

输出格式

对于本地交互库,交互库最后会输出两行:

第一行两个数 w,dw,d ,分别表示你获胜的场数和平局的场数;

第二行为你的得分。

提示

保证交互库采用完全随机选取策略,即每次均会从未选取的面包中等概率选取一个面包

18001800 场游戏中,有 600600 场是由你的程序先选取,有 12001200 场是由交互库先选取。

具体来说,对于第 ii 场游戏,若 imod3=0i \bmod 3 =0 ,则由你的程序先选取,否则由交互库先选取。

本题首先会受到和传统题相同的限制,例如编译错误会导致整道题目得 00 分,运行时错误、超过时间限制、超过空间限制等会导致相应测试点得 00 分等。

你只能访问自己定义的和交互库给出的变量及其对应的内存空间,尝试访问其他空间将可能导致编译错误或运行错误。

本题只有一个测试点,你的得分按如下规定判定:

设你程序获胜了 xx 场,平局为 yy 场,你最终的得分用计分函数 f(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 $$

最低得分为 00 分。

实际评测的交互库与下发的不相同,选手的程序应不依赖于交互库实现

详细可查看template_game.cpp