题目链接:题目原文
题目大意:
起初玩家站在h高度的悬崖,接下来有h个平台,每个平台都有两个状态
(隐藏或者显现),然后给出n个平台,代表这些平台的起初状态是显现
的,对于玩家当前处于的平台x,玩家如果跳下去,那么x和x-1平台的状
态都会改变(跳下时,改变状态的只能是x和x-1高度的平台,如果是隐藏,
则改变为显现,反之也是如此。玩家最多承受从x跳到x-2的距离,如果这
个距离大于2,则玩家死亡(例如玩家处于x平台,但是x-1平台是显现,
x-2平台是隐藏,则玩家只能跳到x-2之下的平台,超过了玩家能承受的
最大距离,玩家阵亡)。但是当玩家使用一个魔法之后,可以任意改变一个
平台的状态,使原本必死的玩家存活下来(根据上面玩家死亡的例子知道,
我们可以该改变x-2高度的平台的状态,让玩家的生命得到保障)。
问:最少使用几个魔法能使玩家成功落地(高度为0)。
第一行测试数据组数T
接下来一行两个数据h,n(h代表悬崖高度,n代表接下来给出n个没有隐藏的平台)
接下来一行n个平台(n个平台是有顺序的,从大到小)
解题思路:
1.假设n个平台的高度为ai,i处于1 ~ n。ai高度的平台最初状态是显现的。
2.假设玩家此时初处于x高度的平台,如果接下来只有ai高度的平台是显现的(即x ~ ai之间高度的平台都是隐藏的),那么玩家可以一直到达ai+1高度的平台(因为x-1高度的平台是隐藏的,当从x高度的平台跳下时,x高度的平台变为隐藏,x-1高度的平台变为显现,刚好玩家可以落到x-1高度的平台,依次类推,玩家最终处于ai+1高度的平台),那么当玩家位于ai+1高度的平台时,就有两种情况,第一种,玩家可以安全跳下,那么ai+1平台的高度必须恰好为ai-1的高度(因为此时玩家从ai+1高度的平台跳下,ai高度的平台变为隐藏,玩家不能跳到ai高度的平台,所以得看ai-1高度的平台是否显现,正好ai+1 == ai-1,ai+1高度的平台是显现的,落下的距离为2,所以玩家还活着),那么这种情况的话,玩家就从x平台直接跳到了ai+1高度的平台,更新玩家所处平台的高度,继续开始判断,重复第二步。第二种,玩家不能安全跳下,根据第一种情况可知,ai+1平台的高度必须小于ai-1(即ai+1高度与ai+1高度的差要大于2),此时跳下,玩家就摔死了,游戏结束,但是我们有魔法,所以我们使用一个魔法,让ai-1高度的平台变为显现,让玩家可以安全的跳到ai-1高度的平台,从而继续进行判断,重复第二步。
3.根据第二点的思路,我们可以对所给的n个平台进行模拟,从而得到答案。
AC代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n, m, h, ans, T;
int a[1000010]; //用来存最初处于显现的平台
int main() {
cin >> T;
while (T--) {
cin >> h >> n;
ans = 0;
for (int i = 1; i <= n; i++) cin >> a[i];
a[n + 1] = 0;
//我们假定在题目给出的n个显现平台之后的平台是0,高度为0的平台也是显现的
for (int i = 1; i < n ; i++) {
//如果i<=n,因为i+2会超出n+1,总不是到地下的去吧~
if (a[i + 1] - a[i + 2] > 1) ans++;
//因为此时玩家处于a[i]的高度,我们可以从解题思路第二步两种情况
//之前的话得知,a[i]高度可以安全降落到a[i+1]+1高度的平台,我们
//就可以把a[i]当作a[i+1]+1,然后根据第二步的思路,判断
//a[i + 1]与a[i + 2]之间的距离是否大于1,如果大于1,我们就得
//使用魔法啦!
else i++;
//如果可以安全降落,即a[i + 1] - a[i + 2] == 1,
//那么直接就到达a[i+2]的平台了
}
cout << ans << endl;
}
return 0;
}
(题解写的真累,本孱弱还得多多写题,练码速,学算法)
冲吧,骚年!