#P50401. 「SNOI2017」魔塔

「SNOI2017」魔塔

Cannot parse: undefinedms error parsing time

题目描述

1 游戏概述

魔塔是 RPG(Role Playing Game,角色扮演游戏)的代表。在这款游戏中,你需要操作勇士与怪物战斗,并用获取的金钱提升自己的能力,从而挑战更强的怪物。而最终的目标,则是营救公主。
与传统的魔塔相比,本题去除了大量的设定,只留下了一些最基本的元素。

2 场地

游戏的场地为一个矩形,被划分为 M×NM\times N 个小方格。
小方格可能是空地,也可能有人或怪物。下面是所有可能出现的状态,用一个字母表示:
a:adventurer,表示勇士的初始位置;
n:表示NPC;
p:princess,表示公主;
m:monster,表示怪物;
o:表示墙壁;
.:表示空地。
NPC、公主、怪物、墙壁均不可穿越,勇士只能向上下左右四个方向相邻(注:之后所有的“相邻”都表示四个方向)的空地移动。移动后,空地与勇士的位置交换。 怪物是唯一可以改变的地形;怪物被消灭后,会变为空地。

3 战斗

触发战斗的条件是勇士所在的位置与怪物相邻
勇士与怪物均拥有三个属性:生命值攻击力防御力。怪物的属性会在游戏开始时给出,且不会改变;而勇士可以通过商店进行购买,同时生命值也会因为战斗而下降。
每一场战斗由勇士先进行攻击,之后怪物攻击,之后勇士攻击,之后怪物攻击……如此循环。
每次攻击所造成的伤害为 max(\max( 攻击者攻击力 - 对方防御力 ,0),0),对方的生命值会扣减这个数值。
任何一方生命值小于等于 00 将会死亡,战斗结束。


战斗举例 1

勇士 生命值 10 攻击力 5 防御力 2
怪物 生命值 10 攻击力 3 防御力 1
勇士先进行攻击,对怪物造成 51=45-1=4 点伤害,怪物生命值为 6;
怪物进行攻击,对勇士造成 32=13-2=1 点伤害,勇士生命值为 9;
勇士进行攻击,对怪物造成 51=45-1=4 点伤害,怪物生命值为 2;
怪物进行攻击,对勇士造成 32=13-2=1 点伤害,勇士生命值为 8;
勇士进行攻击,对怪物造成 51=45-1=4 点伤害,怪物生命值为 -2,死亡!
在这场战斗中,勇士消灭怪物,损失了 2 点生命值。

战斗举例 2

勇士 生命值 10 攻击力 5 防御力 6
怪物 生命值 10 攻击力 5 防御力 2
由于怪物对勇士造成的伤害为 0,而勇士对怪物造成的伤害不为 0,故结果为勇士消灭怪物,损失 0 点生命值。

当勇士死亡,或战斗进入无限循环(两方伤害均为 0)时,均为勇士失败,游戏立即结束。

4 商店

勇士可以进入商店购买物品。商店可以在任何时候使用,与勇士当前位置无关。
勇士拥有初始金钱,同时每个怪物被消灭时也会掉落一定的金钱
在商店里,属性以物品的形式呈现。每个物品包括了价格、生命值、攻击力、防御力、存量几个属性。
勇士支付对应的价格后,即可获得这一商品的生命值、攻击力、防御力,并直接加到自己的属性上。此外,勇士够买这一商品的次数不能超过其存量。

5 对话

触发对话的条件是勇士与 NPC 或公主相邻
勇士可以与场地中的 NPC 对话,NPC 会给勇士人生的经验
这些对话在大多数时候只起到为 RPG 渲染环境的作用,但有时,这些对话对过关有提示作用。极少数情况下,NPC 的对话会与游戏规则抵触,此时以 NPC 对话内容为准。
最后,勇士可以与公主对话,对话之后营救成功,游戏立即结束,公主同样会留下一段感谢的话。

6 目标

游戏的目标是,在营救公主时,保留尽可能多的生命值。生命值会按照一定的规则,转化为公主的爱意值,也即 1 到 10 之间的整数。
若未成功营救公主(战斗时死亡、无限循环,操作不合法等),则算作未完成游戏目标,爱意值将被记为 0。

输入格式

这是一道提交答案型试题,你不需要提交你的源程序。你只需根据给出的 10 个输入文件,使用适当的方法编写 10 个输出文件并提交。
所有的输入文件 mota1.in ~ mota10.in 已在对应的目录下。

输入文件 motaX.in第一行是两个正整数 NNMM,表示场地的宽与长。
接下来 NN 行,每行 MM 个字符,为“场地”中所对应的字符,中间没有空格。这些字符中,保证勇士 a 与公主 p 恰好出现一次。
接下来一行包括四个空格隔开的整数 Cash,Health,Atk,Def\text{Cash}, \text{Health}, \text{Atk}, \text{Def},分别表示勇士的初始金钱、初始生命值、初始攻击力、初始防御力。
接下来一行为一个整数 PP,表示怪物的数量。
接下来 PP 行,每行有六个空格隔开的整数 cash,hp,atk,def,x,y\text{cash},\text{hp},\text{atk},\text{def},x,y,描述了一只怪物,分别表示击杀怪物获得的金钱、怪物生命值、怪物的攻击力、怪物的守备力、怪物的行坐标、怪物的列坐标(也即:怪物在第 xx 行,第 yy 列)。保证场地中的每个 m 所对应的坐标,均在本段恰好出现一次。
接下来一行为一个整数 RR,表示商店中物品的种类。
接下来 RR 行,每行有五个空格隔开的整数 cash,hp,atk,def,num\text{cash},\text{hp},\text{atk},\text{def},\text{num},描述了一件物品,分别表示商品的价格,购买之可以获得的生命值、攻击力、防御力,以及商品存量。
输入文件结束。

输出格式

对应每一个输入文件,你需要编写 mota1.out ~ mota10.out 放在对应的目录下。
你的输出需要包括若干行,每行描述了一个操作。下方列出了可能的操作,实际使用时,需要用对应的数字替换尖括号里(含尖括号本身)的内容:

MOVE <X> <Y>
内容:表示移动到坐标为第 XX 行,第 YY 列的地点。允许在一次操作中进行多次移动,从而直接移动到目标点。
条件:(X,Y)(X,Y) 必须为空地,且可以从勇士所在位置经过若干次向相邻方格的移动达到。

ATTACK <X> <Y>
内容:对第 XX 行,第 YY 列的怪物发起攻击。结算勇士各项属性及金钱变化,并进行死亡判定。
条件:(X,Y)(X,Y) 必须为怪物,且勇士所处位置与其相邻。

TALK <X> <Y>
内容:与第 XX 行,第 YY 列的 NPC 或公主进行对话。对话的结果会输出到屏幕。如果对话的是公主,则游戏结束,此行之后的内容会被忽略。
条件:(X,Y)(X,Y) 必须为 NPC 或公主,且勇士所处位置与其相邻。

BUY <S> <T>
内容:购买第 SS 种商品 TT 件。结算勇士各项属性及金钱变化。
条件:购买商品后自己金钱不小于 0。

你的输出不能超过 100000 行。

样例

3 4
.mmp
.ooo
a...
0 10 5 2
2
10 10 3 1 1 2
10 10 5 2 1 3
3
10 100 0 0 1
5 0 2 0 2
5 0 0 2 2
MOVE 1 1
ATTACK 1 2
BUY 3 2
MOVE 1 2
ATTACK 1 3
BUY 1 1
MOVE 1 3
TALK 1 4

勇士向 (1,1)(1,1) 移动后,攻击 (1,2)(1,2) 处的怪物。 勇士的属性为 (10,5,2)(10,5,2),怪物的属性为 (10,3,1)(10,3,1)。这是战斗系统中的例子,勇士损失 22 点生命,消灭怪物获得 1010 金钱。此时,(1,2)(1,2) 变为空地。 勇士购买 33 号商品 22 件,也即 44 点防御,此时属性为 (10,5,6)(10,5,6)。 勇士向 (1,2)(1,2) 移动后,攻击 (1,3)(1,3) 处的怪物。这也是战斗系统中的例子,勇士无伤消灭怪物,获得 1010 金钱。 勇士购买 11 号商品 11 件,也即 100100 点生命。此时勇士生命为 108108。 勇士向 (1,3)(1,3) 移动后与位于 (1,4)(1,4) 的公主对话,游戏结束。 可以证明,108108 是勇士通关时可能的最大生命值。

数据范围与提示

数据范围

1N,M10001 \leq N,M \leq 10000R10000000 \leq R \leq 1000000; 其它提及的参数均为整数且不超过 101210^{12}

评分方法

我们提供了 mota1.ans ~ mota10.ans 这十个文件,分别对应了计算爱意值的参数。每个文件包含 9 个空格隔开的整数,分别为 a10,a9,,a2a_{10},a_9,…,a_2。我们约定 a1=0a_1=0
对于每个测试点,设勇士最后的生命值HH,形式化地,爱意值为满足 HaiH\geq a_i 的最大 ii 值。
你的得分为 10 个测试点中,爱意值的总和。

如何测试你的输出

我们提供了 motacheck.exe 这个程序来测试你的输出。考虑到大多数选手的情况,这里只提供 Windows 下的测试方法。
使用时,请确保 mota1~10.inmota1~10.outmota1~10.ansmotacheck.exe 均在同一目录下。
此时运行 motacheck.exe,会产生一个文件 mota.log,表示了测试结果。
这个文件会包括 11 行,其中,前 10 行分别表示每个测试点的爱意值,而最后一行为你的总分。

checker 的其它用法

motacheck.exe 还有其它用途。请注意:这是观看 NPC 对话的必备方式
在 Windows 下,按住 Shift 后右键点击当前目录下的空白处,选择“在此处打开命令窗口”;或在命令提示符下输入“cd \对应目录”,进入对应目录。
例如,本题所有文件均在目录 E:\ABC\mota\ 下,则你需进行的操作是:
打开 E:\ABC\mota\,右键单击空白处并选择“在此处打开命令窗口”

输入 E: 回车
输入 cd \ABC\mota 回车

输入 cd /d E:\ABC\mota 回车
此时屏幕上会显示 E:\ABC\mota> ,这表明已经进入对应目录。

你可以输入 motacheck X 其中 XX 为任意正整数,即可测试第 XX 组数据。
例如,输入
motacheck.exe 1 回车
表明需要测试第一组数据。
此时,所有与 NPC 和公主的对话会以中文显示在屏幕上。
如果你的输出不合法,则会以中文输出错误内容,格式通常为:
测试终止于第 L 行,错误 XXX:YYYYYYYYY
这表示错误发生在你的输出的第 LL 行,XXX\text{XXX} 为错误编号,YYYYYYYY\text{YYYYYYYY} 为错误内容。

你也可以将 XX 定义为大于 1010 的数,这可以帮助你自己编一些数据来测试你的程序的正确性。
使用自编的数据时,请保证:
.in.out.ans 文件均存在,且满足上面的输入格式。我们不检查 .in.ans 的格式,如果输入错误可能不会有报错信息。
注意:只有原始的 10 组数据可以触发 NPC 对话,自编的数据中与 NPC 对话会进入时间的裂缝,NPC 无法提供有效对话。

此外,我们提供了一些可选的参数:
-b 屏蔽与 NPC 和公主的对话,并将分数单独显示。
-d <文件名> 开启调试模式。程序将在每一步输出勇士的行坐标、列坐标、生命值、攻击力、防御力、金钱到文件中,如文件已存在则覆盖。如不指定文件名,则输出到 debug.log
-h 显示此帮助。
-o <文件名> 将对话内容输出到文件中。如不指定文件名,则输出到 output.log
-p <文件名> 评测模式,此参数替代 XX,且覆盖其它参数。将选手的 10 组输出变为评测机可以接受的形式,保存为 cpp 文件。如不指定文件名,则输出到 mota.cpp
-s <文件名> 简化模式,此参数替代 XX,且覆盖其它参数。直接向文件输出选手的得分(与无参数相同)。如不指定文件名,则输出到 mota.log

形式化地,motacheck 的使用方式为:
motacheck [ X | -p [<file>] | -s [<file>] ] [ -b ] [ -d [<file>] ] [ -o [<file>] ]

注意:由于 SNOI 只提供了一个 checker 的 exe 文件,且其内容十分丰富难以仿制,故我们无法在线上评测。请您自行使用 checker 进行评测。