#L2699. 「POI2012 R3」拍卖 Bidding

「POI2012 R3」拍卖 Bidding

题目描述

译自 POI 2012 Stage 3. Day 1「Bidding」

Alojzy 和 Bajtazar 正在玩一场拍卖游戏。这款游戏需要一大堆小石子。两人轮流行动:先由 Alojzy 开始,然后是 Bajtazar,再次轮到 Alojzy,依此类推。

游戏中,关键是两个值:当前竞价堆栈大小

  • 游戏初始时,竞价为 11 个石子,堆栈为空。
  • 每轮中,玩家可选择以下动作之一:
    1. 将竞价翻倍
    2. 将竞价增至三倍
    3. 弃牌

若玩家弃牌,当前竞价全部加入堆栈(这是堆栈增大的唯一方式),然后竞价重置为 11 个石子。弃牌后,由对手进行下一轮(Alojzy 仅在游戏开始时首轮行动)。

输掉游戏的条件

  1. 若堆栈中的石子达到或超过 nn 个,触发堆栈溢出,当前玩家输掉游戏。
  2. 若玩家行动前,堆栈和竞价中的石子总数达到或超过 nn,该玩家无法翻倍或增至三倍,只能弃牌,将竞价加入堆栈,从而输掉游戏。

Alojzy 总是输多赢少。Bajtazar 提出一个有趣的挑战:与其亲自玩,不如编写程序代为对战。请你编写一个程序,代表 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/C++ 调用 Pascal 调用 结果 堆栈 竞价 说明
n = inicjuj(); n := inicjuj; 15 0 1 从此刻起 n=15n=15
alojzy(2); - 2 你的程序将竞价翻倍
bajtazar(); bajtazar; 2 4 库回应翻倍竞价
alojzy(3); - 12 你的程序将竞价增至三倍
bajtazar(); bajtazar; 1 12 1 库弃牌,1212 个石子加入堆栈,竞价重置为 11
alojzy(2); - 2 你的程序将竞价翻倍
bajtazar(); bajtazar; 3 6 库将竞价增至三倍
alojzy(1); - 18 1 堆栈和竞价石子总数超过 1515,你的程序被迫弃牌

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


数据范围与提示

  • 在所有测试数据中,只要你的程序做出正确选择,就能获胜。仅当程序击败库时,该测试数据才会得分。
  • 对于 50%50\% 的测试数据,n25n \leq 25
  • 所有测试数据满足 1n300001 \leq n \leq 30000