众所周知:时代在变迁。“三重镇”是 NOI(全国青少年信息学奥林匹克竞赛)2012 的一道提交答案题,题目原文见下:
小西同学最近喜欢上了 iOS 游戏《三重镇 Triple Town》。游戏之余,小西也在思考如何才能在这个游戏中获得更高的分数。 如图 1 所示,游戏在一个 n∗m 的地图中进行。游戏给定一个建造序列,玩家按照此建造序列依次选择空白位置建造相应的建筑单位。建筑有九个不同的等级,由低到高分别为 Grass, Bush, Tree, Hut, …等(为了方便描述,我们称之为 L1,L2,L3,…,L9)。

当玩家在一个空白位置建造单位之后,有可能引起反应。反应的构成条件是:从这个格子出发,与该建筑单位等级相同的格子所构成的连通块大小大于等于3, 则这个连通块将被合并为一个下一等级的建筑,此建筑的位置为最后建造的建筑单位位置,连通块中其他位置将变回空格。这里的连通块是指直接或者间接相邻的位置集合。另外需要注意的是,L9为建筑的最高等级,所以多个 L9 的连通块并不会合并。例如在图 2 中,当建造了中间的 L1 之后,与该位置相连的 L1就被合并成了一个 L2。

注意,在合并的过程中,可能会引起连环反应。如下图所示。

游戏的得分取决于玩家建造和反应生成的单位,建造或者反应生成建筑单位就可以获得相应的分数。不同等级建筑的得分表如下:
| 建筑 | L1 | L2 | L3 | L4 | L5 | L6 | L7 | L8 | L9 |
|---|---|---|---|---|---|---|---|---|---|
| 得分 | 4 | 20 | 100 | 500 | 1,500 | 5000 | 20000 | 100000 | 500000 |
以刚才的两个游戏过程为例。图 2 中,首先建造了 L1, 将得到 4 分,随后, L1 进行了反应生成了 L2, 此时再得到 20 分。总共得分为 24。而在图 3 中,这一 步操作得分为 4+20+100+500=624 分。 为了降低游戏的难度,游戏中还设有两种道具,分别为星星和炸弹。在游戏开始时,玩家被给定 p 个星星道具和 q 个炸弹道具,玩家可以在任意时刻使用。两者功能如下:
| 名称 | 用途 |
|---|---|
| “星星”道具 | 可以放置在一个空格位置。当星星被放置时,星星会自动变为能引起反应的最高等级建筑。当在该位置不能引起任何反应时,星星变为 L1。 例如,在图 3 正中间位置放置星星,星星自动变为 L3。星星的得分按照变化后的建筑计算得分。 |
| “炸弹”道具 | 炸弹道具可以放在在一个有建筑的位置上,作用为炸掉这个建筑并将该位置恢复为空格。当使用炸弹时,得分将扣除被炸掉的建筑的一半分数 (即,得分为负数)。 |
在游戏的进行过程中,玩家必须按照给定的顺序进行建造,但可以随时穿插使用两种道具。游戏的目标是,通过合理的操作,取得最高的分数。
该题为提交答案型试题,所有输入数据 tritown1.in ~ tritown10.in 放置在附加文件内。
对于每个数据,输入文件中第一行为两个整数 n, m, 表示地图一共包含 n 行 m 列。
接下来一行包含两个整数 p, q,分别表示道具星星和道具炸弹的数目。
接下来 n 行包含一个 n∗m 的初始地图。其中字符“.”表示空地,数字 1∼9 分别表示相应等级的建筑。
再接下来一行包含一个数字 k, 表示建造序列的长度。
最后一行包含 k 个空格隔开的 1∼9 之间的数字,表示建造序列的内容。
针对给定的 10 个输入文件 tritown1.in ~ tritown10.in,你需要分别提交你的输出文件 tritown1.out ~ tritown10.out。
输出文件包含玩家进行游戏的指令,共 4 种指令:
| 指令 | 含义 |
|---|---|
PUT x y |
将建造序列中的下一个单位放置到第 x 行第 y 列的空格中。 |
STAR x y |
放置星星道具到第x行第y列的空格中。 |
BOMBER x y |
在第 x 行第 y 列放置炸弹,此位置必须非空。 |
END |
游戏结束,结算当前得分。 |
输出必须以 END 指令结尾,玩家可以在任意时刻结束游戏。
2 3
1 1
..1
221
2
1 3
PUT 1 2
PUT 1 1
STAR 2 1
END

第一步得分为 4+20+100=124;
第二步得分为 100;
第三步得分为 100+500=600;
游戏总得分 124+100+600=824 分。
对于每组数据,我们设置了 9 个评分参数 a10,a9,…,a2,它们按此顺序每行一个放置在附加文件中的 tritown1.ans ~ tritown10.ans 内。如果选手的输出不合法,则得零分。否则,设在你的方案中,游戏得分为 wuser,你的分数将会由下表给出:
| 得分 | 条件 | 得分 | 条件 |
|---|---|---|---|
| 10 | wuser≥a10 | 5 | wuser≥a5 |
| 9 | wuser≥a9 | 4 | wuser≥a4 |
| 8 | wuser≥a8 | 3 | wuser≥a3 |
| 7 | wuser≥a7 | 2 | wuser≥a2 |
| 6 | wuser≥a6 | 1 | wuser>0 |
如果有多项满足,则取满足条件中的最高得分。
我们提供 checker 这个放置在附加文件中的工具来测试你的输出文件是否是可接受的。
使用这个工具的方法是,在 命令提示符 中运行(请先将 命令提示符 切换到该工具的目录下):
./checker_win32 <case_no>
其中<case_no>是测试数据的编号。例如
./checker_win32 3
将测试tritown3.out是否可以接受。
在你调用这个程序后,checker 将根据你给出的输出文件给出测试的结果,其中包括:
Output File Do Not Exist:找不到输出文件;Output Invalid!:输出文件有误,此时可能包含具体错误信息;Correct! Your score is x:输出可接受,你的得分 x。请妥善保存你的输出 tritown*.out,及时备份,以免误删。
对于这道题最后两个测试点,命题人在当年 NOI 年鉴上给出了编程辅助“手算”(即写一个这样的游戏,手玩并记录结果)的解决方案。这种方案,体现了当时时代的局限性。众所周知,当今这个时代,我们岂能不用“AI”来解决这个问题。
请提供一个程序,输入即为上文所述题目的最后两个测试点,输出按上文要求输出。当你这两个点的得分均为 10 分时,你就可以通过本题。由于评测时你的程序运行时间有限,你可以将预先计算好的结果直接输出。
原题是一道提交答案题,其测试数据和 checker 可从此处下载。