本题是道阅读理解题,读懂题意了就可破。

题意:

就是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;
}