LuoguP5006 [yLOI2018] 大美江湖 题解
Content
题意实在是太过复杂了,因此请回到题面查看。
Data Range
本部分和 Solution 部分变量的含义同题面。
- \(1\leqslant n,m\leqslant 100,0\leqslant q\leqslant 10^4,0\leqslant ST_0,DE_0,HP_0,ST,DE\leqslant 100,1\leqslant op\leqslant 2,1\leqslant d\leqslant 4\)。
- \(C_{i,j}\) 只有可能是
.
,R
,Q
,Y
,M
五个字符之一。 - 人物不会跑到地图外面。
Solution
不知道为什么被扶咕咕给改了题面……所以又重新做了一遍。
而且为什么一下扶苏一下炮姐啊,好混乱啊,搞得我都弄不清主人公到底是谁了。
分部分来讲:
Part 1 Test Data 1
因为 \(q=0\),也就是说没有提问,因此,你不需要输出任何东西就可以骗到这道题目的 \(10\) 分。
这部分分可以说对于萌新非常非常友好。
Part 2 Test Data 4,5
人物只固定在一个点上面游走,因此每次询问的答案一定分别是 \(0,ST\) 和 \(DE\)。输出 \(q\) 次即可拿到 \(20\) 分。
这部分分也可以说对于萌新是非常友好的。因此,我可以说,只要你会语法,这道题目至少可以拿到 \(30\) 分。
Part 3 Test Data 6~8
开始进入我们的正题了。由于这一部分没有怪物,所以我们只需要讨论捡到生命药水、力量药水和防御药水时的情况。
在此之前还需要考虑移动的情况,原来的题面当中是直接输入一个字符然后依此判断行动方向。而这里直接输入数字的话就很简单了,我们可以直接开一个数组,然后输入时将其作为数组的下标,就可以直接加进去当前位置的坐标里面去了。
再具体分析捡到三种药水的情况:
- 生命药水:变化就是 \(HP\leftarrow\max(0,HP-10)\)。
- 力量药水:变化就是 \(ST\leftarrow ST+5\)。
- 防御药水:变化就是 \(DE\leftarrow DE+5\)。
由于捡到药水之后药水不会消失,因此不需要考虑是否已经捡到的情况。
Part 4 Others
捡到药水的情况我已经在上面讲过了,所以接下来就是考虑打怪时的情况。这里直接给了个式子给你:
\[\max(1,\left\lceil\dfrac{HP_0}{\max(1,ST-DE_0)}\right\rceil\times\max(1,ST_0-DE))
\]
你就直接按照这个式子算就好了。注意在使用 cmath 库里面的 ceil 函数时,不能够直接除,要先把被除数或者除数转换成 double 类型,然后再去除,最后向上取整之后用整型变量存储就好。
上面的所有变化用变量存储一下,询问的时候就直接输出就好了。
所以这道题目就做完了,还算是一道比较小清新的模拟题。
Code
const int dx[5] = {0, 0, 0, -1, 1};
const int dy[5] = {0, -1, 1, 0, 0};
struct misaka {
int hp0, st0, de0, curx, cury;
}fusu;
int n, m, hp, st, de, q;
char a[107][107];
int main() {
n = Rint, m = Rint;
F(i, 1, n) scanf("%s", a[i] + 1);
hp = Rint, st = Rint, de = Rint, fusu.curx = Rint, fusu.cury = Rint, fusu.st0 = Rint, fusu.de0 = Rint, q = Rint;
while(q--) {
int op = Rint;
if(op == 1) printf("%d %d %d\n", fusu.hp0, fusu.st0, fusu.de0);
else {
int d = Rint;
fusu.curx += dx[d], fusu.cury += dy[d];
if(a[fusu.curx][fusu.cury] == 'R') fusu.hp0 = max(0, fusu.hp0 - 10);
else if(a[fusu.curx][fusu.cury] == 'Q') fusu.st0 += 5;
else if(a[fusu.curx][fusu.cury] == 'Y') fusu.de0 += 5;
else if(a[fusu.curx][fusu.cury] == 'M') fusu.hp0 += max(1, (int)ceil(hp * 1.0 / (max(1, fusu.st0 - de) * 1.0)) * max(1, st - fusu.de0));
}
}
return 0;
}