本题是道阅读理解题,读懂题意了就可破。
题意:
就是h个平台,初始在h高度上,事先已经使n个平台已开,当你需要下降时,事先必须有now-1的状态为开
且每次最多下降2格,当你无法满足条件来下降时,可花费一块水晶来调整平台状态,问你最少要多少水晶来到达地面
注意下h <= 1e9
用数组存储即可,刚开始弄错题意错用unordered_set TLE了。
题解:
本题的思路是,我们一定从h高度开始下降
当我们从下降时,判断下当前所处位置now的下两个位置的平台状态,即now-1和now-2的状态
1.若两者皆开,可直接到now-2处,
2.若now-1开,now-2关,花费一块水晶将now-2打开,可直接到now-2
3.若now-1关,可直接到now-1
根据上述所有情况再具体实现为:我们每次都一定可以先到达系统事先给出的已开平台的上一层,这样的话就避免了上述的第3种情况,只需判断1和2即可。
当我们到达了系统给定的当前最高的已开平台的上一层,我们便无需判断now-1了,now-1必关,判断p[i + 1] 是否等于now-2,等于则表示now-2为开,否则说明p[i + 1] < now-2那么我们直接花费水晶到now-2,之后继续循环即可。
这里有个细节要注意,p[n] = 0,主要是为了判断,当now = p[n - 1] + 1, now > p[n] + 2则说明我们当前的位置前还有个p[n - 1]是开的,想跨过去的话由于p[n - 1] > 1则必须花费一个水晶,况且由于多组所以必须设置p[n] = 0防止上组数据的影响。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 100;
int p[N];
int n, h;
int main()
{
int q;
scanf("%d", &q);
while(q--){
scanf("%d%d", &h, &n);
for(int i = 0; i < n; i++) scanf("%d", &p[i]);
p[n] = 0;
int ans = 0;
for(int i = 1; i < n; i++){
if(h > p[i] + 1) h = p[i] + 1;
if(h > p[i + 1] + 2){
h -= 2;//这里是到now-2,是开now-2
//h--也可,即关now-1
ans++;
}
else h = p[++i];
}
printf("%d\n", ans);
}
return 0;
}