#HK2699. 「POI2012 R3」拍卖 Bidding

「POI2012 R3」拍卖 Bidding

题目描述

译自 POI 2012 Stage 3. Day 1「Bidding

Alojzy 和 Bajtazar 正在玩一场拍卖游戏。这款游戏需要一大堆小石子。两人轮流行动:先由 Alojzy 开始,然后是 Bajtazar,再次轮到 Alojzy,依此类推。游戏中,关键是两个值:当前竞价和堆栈大小。游戏初始时,竞价为 11 个石子,堆栈为空。每轮中,玩家可选择以下动作之一:

  • 将竞价翻倍,
  • 将竞价增至三倍,
  • 弃牌。

若玩家弃牌,当前竞价全部加入堆栈(这是堆栈增大的唯一方式),然后竞价重置为 11 个石子。弃牌后,由对手进行下一轮(Alojzy 仅在游戏开始时首轮行动)。若堆栈中的石子达到或超过 nn 个,触发堆栈溢出,当前玩家输掉游戏。若玩家行动前,堆栈和竞价中的石子总数达到或超过 nn,该玩家无法翻倍或增至三倍,只能弃牌,将竞价加入堆栈,从而输掉游戏。

Alojzy 总是输多赢少。Bajtazar 提出一个有趣的挑战:与其亲自玩,不如编写程序代为对战。可惜,Alojzy 不会编程。请你帮他编写一个程序,代表 Alojzy 与 Bajtazar 的库进行拍卖对战。

交互方式

程序需在开头引入库:

  • C/C++: #include "cliclib.h"
  • Pascal: uses pliclib;

库提供以下函数和过程:

  • inicjuj:返回 nn,需在程序开始时调用一次。
    • C/C++: int inicjuj();
    • Pascal: function inicjuj: longint;
  • alojzy:通知库你的程序的动作。参数为整数 xx,表示动作:x=1x=1 为弃牌,x=2x=2 为翻倍,x=3x=3 为增至三倍。
    • C/C++: void alojzy(int x);
    • Pascal: procedure alojzy(x: longint);
  • bajtazar:返回库的动作,返回整数 xx,表示动作:x=1x=1 为弃牌,x=2x=2 为翻倍,x=3x=3 为增至三倍。
    • C/C++: int bajtazar();
    • Pascal: function bajtazar: longint;

调用 inicjuj 后,需交替调用 alojzybajtazar(按此顺序)。违反通信协议将被判为「Wrong Answer」,该测试数据得 00 分。本任务禁止使用标准输入输出,所有通信仅通过上述函数和过程进行。库将在游戏结束后自动终止程序。

程序将与库一起编译,使用以下命令:

  • 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

示例评测程序

在「文件」下,有示例库文件和非最优示例解法,展示库的使用方法。与示例库编译的程序从标准输入读取 nn,随后持续读取 Bajtazar 的动作,模拟 Alojzy 的策略,并将游戏详细过程输出到标准错误输出(stderr)。在评测测试数据中,Bajtazar 的动作顺序为:弃牌、翻倍、增至三倍、弃牌、翻倍、增至三倍,循环往复。

最终评测将使用另一组库。

样例

以下表格展示了一场示例程序运行的函数调用序列及 dojrzale 的正确结果:

C/C++ 调用 Pascal 调用 结果 堆栈 竞价 说明
n = inicjuj(); n := inicjuj; 1515 00 11 从此刻起 n=15n=15
alojzy(2); alojzy(2); - 00 22 你的程序将竞价翻倍。
bajtazar(); bajtazar; 22 00 44 库回应翻倍竞价。
alojzy(3); alojzy(3); - 00 1212 你的程序将竞价增至三倍。
bajtazar(); bajtazar; 11 1212 11 库弃牌,1212 个石子加入堆栈,竞价重置为 11 个石子。
alojzy(2); alojzy(2); - 1212 22 你的程序将竞价翻倍。
bajtazar(); bajtazar; 33 1212 66 库将竞价增至三倍。
alojzy(1); alojzy(1); - 1818 11 堆栈和竞价石子总数超过 1515,你的程序被迫弃牌。

上述程序运行正确但非最优,你的程序不会因通过了此样例而得分。特别是,对于 n=15n=15,Alojzy 存在必胜策略,无论 Bajtazar 如何行动。

数据范围与提示

在所有测试数据中,只要你的程序做出正确选择,就能获胜。仅当程序击败库时,该测试数据才会得分。

对于 50%50\% 的测试数据,n25n \leq 25
所有测试数据满足 1n300001 \leq n \leq 30000