B. Heaters 思维题 贪心 区间覆盖
这个题目虽然只有1500的分数,但是我还是感觉挺思维的,我今天没有写出来,然后看了一下题解
很少做这种区间覆盖的题目,也不是很擅长,接下来讲讲我看完题解后的思路。
题目大意是:给你一个数列,这个数列的0代表这个地方没有加热器,1代表有,每一个加热器的范围是 [i-r+1,i+r-1]
问你用最少多少个加热器让整个数列都被加热。
我们可以把加热器都放入一个队列,然后用一个数haves来表示[1,haves]的范围已经被覆盖,然后再用一个数now 来表示 根据上一个点
这一个点可以选择的最远位置,如果最远都不能找到满足要求的点就表示不可以覆盖。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstring> #include <queue> #include <cstdlib> #include <cstdio> #include <iostream> #include <string> #include <bitset> #include <algorithm> #include <map> #include <vector> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; const int maxn = 1e5 + 10; int main() { int n, r; queue<int>que; scanf("%d%d", &n, &r); for(int i=1;i<=n;i++) { int x; scanf("%d", &x); if (x) que.push(i); } int haves = 0, now = r, ans = 0; while(!que.empty()) { int u = que.front(); que.pop(); if (haves >= n) break; if (u > now) { printf("-1\n"); return 0; } if(!que.empty()) { int v = que.front(); if (v <= now) continue; ans++; haves = u + r - 1; now = u + 2 * r - 1; } else { ans++; haves = u + r - 1; now = u + 2 * r - 1; } } if (haves >= n) printf("%d\n", ans); else printf("-1\n"); return 0; }