P10132 Cannonball 题解
题意简述
你的初始位置为
在
如果你在
解题思路
暴力做法
直接暴力模拟弹跳过程。注意同一个目标的击碎条件可能会多次被满足,所以只能在过程中记录目标的击碎情况,最后再统计。
这种做法没有考虑在
核心代码:
ll pos = s, ctar = 0, power = 1;
bool dir = true; // true 表示向右, false 表示向左
while (pos >= 1 && pos <= n) {
if (type[pos] == 0) {
power += val[pos];
dir ^= 1;
} else if (type[pos] == 1) {
if (power >= val[pos]) {
ctar ++;
broken[pos] = 1;
}
}
if (dir) pos += power;
else pos -= power;
}
满分做法
加两行,
说人话就是加入特判弹跳无限次的情况。在每次循环时统计总共的弹跳次数,最后在弹跳次数大于
如果弹跳无限次,那么一定存在一个弹跳循环,而这个循环的最大长度是
那为什么要选择
那怎么确定
核心代码:
ll pos = s, ctar = 0, power = 1, jumpcnt = 0;
bool dir = true; // true 表示向右; false 表示向左
while (pos >= 1 && pos <= n) {
jumpcnt ++;
if (type[pos] == 0) {
power += val[pos];
dir ^= 1;
} else if (type[pos] == 1) {
if (power >= val[pos]) {
ctar ++;
broken[pos] = 1;
}
}
if (dir) pos += power;
else pos -= power;
if (jumpcnt > 3 * n) break;
}