题意描述:
Vova先生的家可以看作一个n×1的矩形,寒冷的冬天来了,Vova先生想让他的家里变得暖和起来。现在我们给你Vova先生家的平面图,其中111表示这个地方是加热炉,0表示这个地方什么也没有。所有加热器都有一个加热半径r,一个位于ai加热器可以加热[ai−r+1,ai+r−1]的范围。现在,Vova先生想让他的整个家都变得暖和,一开始所有的加热器都是关闭的,请你求出Vova先生最少要开几个加热器才能使整个家变得暖和
输入输出格式:
输入格式:
第一行:两个整数n,r(1≤n,r≤1000),含义如上
第二行,n个整数,表示Vova家的地图
输出格式:
一个整数,表示Vova先生至少要打开几个加热器
思路:
还是很水
因为我们要尽可能少,所以我们要用贪心的思想
我们从最左边开始扫,扫到一个没有被加热的点,我们就以这个点为起点向右扫,扫到能加热他的离他最远的一个加热器打开
(贪心的正确性在于这个加热器离他最远且能将它加热,如果选更近的则不更优,选更远的就加热不了他了)
然后将该加热器能加热的范围内的点打标记,继续扫下去即可
最坏时间复杂度O(N^2)
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define rii register int i #define rij register int j using namespace std; int n,r,jz[4005],jrq[4005],bj[4005],ans; int main() { int cnt=0; scanf("%d%d",&n,&r); for(rii=1;i<=n;i++) { scanf("%d",&jz[i]); if(jz[i]==1) { cnt++; jrq[cnt]=i; } } for(rii=1;i<=n;i++) { if(bj[i]==0) { int wz=0; for(rij=1;j<=r;j++) { if(i+j-1<=n) { if(jz[i+j-1]==1) { wz=max(wz,i+j-1); } } if(i-j+1>=1) { if(jz[i-j+1]==1) { wz=max(wz,i-j+1); } } } for(rij=1;j<=r;j++) { if(wz-j+1>0) { bj[wz-j+1]=1; } bj[wz+j-1]=1; } ans++; if(wz==0) { printf("-1"); return 0; } } } printf("%d",ans); }