#HK2699. 「POI2012 R3」拍卖 Bidding
「POI2012 R3」拍卖 Bidding
题目描述
译自 POI 2012 Stage 3. Day 1「Bidding」
Alojzy 和 Bajtazar 正在玩一场拍卖游戏。这款游戏需要一大堆小石子。两人轮流行动:先由 Alojzy 开始,然后是 Bajtazar,再次轮到 Alojzy,依此类推。游戏中,关键是两个值:当前竞价和堆栈大小。游戏初始时,竞价为 个石子,堆栈为空。每轮中,玩家可选择以下动作之一:
- 将竞价翻倍,
- 将竞价增至三倍,
- 弃牌。
若玩家弃牌,当前竞价全部加入堆栈(这是堆栈增大的唯一方式),然后竞价重置为 个石子。弃牌后,由对手进行下一轮(Alojzy 仅在游戏开始时首轮行动)。若堆栈中的石子达到或超过 个,触发堆栈溢出,当前玩家输掉游戏。若玩家行动前,堆栈和竞价中的石子总数达到或超过 ,该玩家无法翻倍或增至三倍,只能弃牌,将竞价加入堆栈,从而输掉游戏。
Alojzy 总是输多赢少。Bajtazar 提出一个有趣的挑战:与其亲自玩,不如编写程序代为对战。可惜,Alojzy 不会编程。请你帮他编写一个程序,代表 Alojzy 与 Bajtazar 的库进行拍卖对战。
交互方式
程序需在开头引入库:
- C/C++:
#include "cliclib.h" - Pascal:
uses pliclib;
库提供以下函数和过程:
inicjuj:返回 ,需在程序开始时调用一次。- C/C++:
int inicjuj(); - Pascal:
function inicjuj: longint;
- C/C++:
alojzy:通知库你的程序的动作。参数为整数 ,表示动作: 为弃牌, 为翻倍, 为增至三倍。- C/C++:
void alojzy(int x); - Pascal:
procedure alojzy(x: longint);
- C/C++:
bajtazar:返回库的动作,返回整数 ,表示动作: 为弃牌, 为翻倍, 为增至三倍。- C/C++:
int bajtazar(); - Pascal:
function bajtazar: longint;
- C/C++:
调用 inicjuj 后,需交替调用 alojzy 和 bajtazar(按此顺序)。违反通信协议将被判为「Wrong Answer」,该测试数据得 分。本任务禁止使用标准输入输出,所有通信仅通过上述函数和过程进行。库将在游戏结束后自动终止程序。
程序将与库一起编译,使用以下命令:
- C:
gcc -O2 -static cliclib.c lic.c -lm - C++:
g++ -O2 -static cliclib.c lic.cpp -lm - Pascal:
ppc386 -O2 -Xs -Xt lic.pas
示例评测程序
在「文件」下,有示例库文件和非最优示例解法,展示库的使用方法。与示例库编译的程序从标准输入读取 ,随后持续读取 Bajtazar 的动作,模拟 Alojzy 的策略,并将游戏详细过程输出到标准错误输出(stderr)。在评测测试数据中,Bajtazar 的动作顺序为:弃牌、翻倍、增至三倍、弃牌、翻倍、增至三倍,循环往复。
最终评测将使用另一组库。
样例
以下表格展示了一场示例程序运行的函数调用序列及 dojrzale 的正确结果:
| C/C++ 调用 | Pascal 调用 | 结果 | 堆栈 | 竞价 | 说明 |
|---|---|---|---|---|---|
n = inicjuj(); |
n := inicjuj; |
从此刻起 。 | |||
alojzy(2); |
alojzy(2); |
- | 你的程序将竞价翻倍。 | ||
bajtazar(); |
bajtazar; |
库回应翻倍竞价。 | |||
alojzy(3); |
alojzy(3); |
- | 你的程序将竞价增至三倍。 | ||
bajtazar(); |
bajtazar; |
库弃牌, 个石子加入堆栈,竞价重置为 个石子。 | |||
alojzy(2); |
alojzy(2); |
- | 你的程序将竞价翻倍。 | ||
bajtazar(); |
bajtazar; |
库将竞价增至三倍。 | |||
alojzy(1); |
alojzy(1); |
- | 堆栈和竞价石子总数超过 ,你的程序被迫弃牌。 |
上述程序运行正确但非最优,你的程序不会因通过了此样例而得分。特别是,对于 ,Alojzy 存在必胜策略,无论 Bajtazar 如何行动。
数据范围与提示
在所有测试数据中,只要你的程序做出正确选择,就能获胜。仅当程序击败库时,该测试数据才会得分。
对于 的测试数据,。
所有测试数据满足 。