D-鬼来了!!
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 39 | Accepted: 11 |
Description
乐乐看了很多鬼故事,他怀疑今天晚上(0:00-6:00这段时间,下面用0-360表示鬼来的时间)会有n个鬼来找他。他现在知道每个鬼来的时间,如果鬼来了,就需要用蜡烛照亮房间,每支蜡烛能燃烧T分钟,最少需要K支蜡烛才能把鬼吓跑。
乐乐想知道他最少需要点多少根蜡烛,才能安全度过今晚。
Input
第一行3个整数n、T、K,含义如题目描述。
第二行n个整数,表示每只鬼来的时间,时间单调递增。
Output
输出需要最少需要点蜡烛数,如果不能把所以的鬼,都吓跑,输出-1.
Sample Input
1 8 3 10 2 10 1 5 8 1 1 3 10
Sample Output
3 1 -1
Hint
如果在第x时刻点一个蜡烛,那么这根蜡烛,会在[x+1,x+T]这段时间,照亮房间。
可以在任何时刻点蜡烛(只能一个),点蜡烛的时间为负数时,表示在午夜前。
对于100%的数据,n、k、T的范围[1,300],鬼来的时间[1,360];
这道题我想了好久,但是主要卡的还是代码实现的方面。
题目的意思是:现在有n只鬼,然后告诉你蜡烛的持续时间只有Ts,并且告诉你要消灭一个怪物要有k个蜡烛,然后第二行给出了n个鬼的出现时间,时间是按照递增顺序的。问你的是要消灭这些怪物最少需要多少蜡烛?
贪心的思想很容易想到,我们为了使蜡烛的数量尽量的少,那么我们就要把蜡烛尽量的从靠近怪物的地方开始点起。
注意这里时间可能会从午夜前开始,所以会产生负的,为了方便,我们直接把时间加上很多,这样就全是正的了。
然后我们首先要判断在当前的鬼的时刻是否安全,for一遍看已有的蜡烛数是不是大于等于所需要的数量,如果没有达到安全水平,那么就从离该鬼出现的时间最近的地方开始插蜡烛,最后再判断一下就好,就可以知道能不能有满足消灭所有的鬼,以及最少的蜡烛数量。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #define N 1005 using namespace std; bool light[2*N]={0};//表示当前时刻是否点蜡烛 int main(){ int n,m,t,r,i,j,k,x,c; scanf("%d %d %d",&m,&t,&r); int ans=0; //x为每个鬼来的时间; //c记录的是目前是总共有多少已经被电亮的蜡烛; for(i=1;i<=m;i++){ scanf("%d",&x); //这里x再加上N的目的是为了防止点蜡烛的时间是负数,那么会不准确; x+=N; c=0; //从当前时刻的前一秒开始判断, for(j=x-1;j>=0;j--)//判断当前时刻是否安全 if(j+t>=x){ c+=light[j]; }else break; //当蜡烛数大于等于所需要的数量时,那么就直接进行下一个循环; if(c>=r)continue; //start :说明此时还未到达安全水平; //这里是贪心算法,从离鬼近的地方开始算起; for(j=x-1;j>=0;j--){//如果不安全,就从后往前点蜡烛 if(j+t<x)break; //当点的蜡烛不能碰到鬼时,那么就跳出循环,并且输出-1; if(!light[j]){ //如果在j这个时刻没有点过蜡烛,那么电亮它,并且标记为1,蜡烛的数量加1; c++;ans++;light[j]=1; } //如果已经有的蜡烛数大于等于需求数,那么就可以把鬼消灭,跳出循环; if(c>=r)break; } //end if(c<r)break; } // if(i<=m)puts("-1"); else printf("%d\n",ans); return 0; }
看了代码,思路就变的开阔起来了。
加油!