1. 程式人生 > >ZCMU1729 C(queue的應用+貪心)

ZCMU1729 C(queue的應用+貪心)

Description

   趙棟棟喜歡看恐怖電影。因此有一次他在做夢時,他夢到了m只鬼。這些鬼很怕光,所以趙棟棟準備了很多蠟燭。每支蠟燭可以正好燃燒t秒。趙棟棟需要1秒去點燃一支蠟燭。也就是說趙棟棟花費1秒去點燃一支蠟燭,然後這支蠟燭會在燃燒t秒後熄滅。對於每隻鬼,趙棟棟知道它們會在什麼時候出現,第i只鬼會在第wi秒出現。並且只持續1秒。趙棟棟想要知道他最少需要準備幾枝蠟燭,才能保證每次當鬼出現時至少有r枝蠟燭是在燃燒的。趙棟棟可以在x秒的時候點燃蠟燭。x必須是整數,但是可以為0和負數。

Input

  輸入包含多組測試資料。每組測試資料的第一行有三個正整數m,t,r(1 <= m, t, r <= 300)。第二行有m個整數wi(1 <= wi <= 300),代表每個鬼出現的時間。所有的wi都不相同並且從小到大排序。

Output

 對於每組測試資料,輸出一行,如果可以滿足條件則輸出最少需要的蠟燭數,否則輸出“-1”。

Sample Input

1 8 3

10

2 10 1

5 8

1 1 3

10

Sample Output

3

1

-1

思路

貪心: 點燃的蠟燭要儘量的少並且滿足條件,那麼點蠟燭的時機應該在鬼出現時的前r秒

不滿足條件的情況如下:

   A.若蠟燭的燃燒時間+(第一個鬼出現的時間-r)<第一個鬼出現的時間,那麼肯定不滿足條件

   B.在每個鬼出現時間的前r秒中,蠟燭的燃燒時間支撐不到鬼出現

程式碼

#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
#define MAX 400
int solve(int *ghost,int n,int time,int r)
{
    if(ghost[1]-r+time<ghost[1])
        return -1;
    queue<int> candle;
    int i,re=r;
    //第一個鬼出現前點好r根蠟燭,進入佇列的數值是點燃蠟燭的那個時間點
    for(i=r; i>=1; i--)
        candle.push(ghost[1]-i);
    for(i=2; i<=n; i++)
    {
        //第i個鬼出現時,之前點的蠟燭已經熄滅的退出佇列
        while(ghost[i]-candle.front()>time)
        {
            candle.pop();
            if(candle.empty()) break;
        }
        //num是點燃蠟燭的最佳時間
        int num=ghost[i]-r+candle.size();
        while(candle.size()!=r)
        {
            if(num>=ghost[i]) return -1;
            candle.push(num++);
            re+=1;
        }
    }
    return re;
}
int main()
{
    int n,time,r;
    int ghost[MAX];
    while(~scanf("%d %d %d",&n,&time,&r))
    {
        int i;
        for(i=1; i<=n; i++)
        {
            scanf("%d",&ghost[i]);
        }
        printf("%d\n",solve(ghost,n,time,r));
    }
    return 0;
}