问题 B: 拯救小鸡
时间限制: 1 Sec
内存限制: 128 MB
提交: 91
解决: 44
[
提交][
状态][
讨论版]
题目描述
鸡国最近遇到了一件很棘手的事情,经常有一只老鹰想来抓小鸡。经鸡国情报员探查,这只老鹰打算共来袭击 n 次,第 i 次来的时刻为第 t i (1≤i≤n) 秒时刻。
鸡国国王为了保护鸡国中的小鸡,决定派出鸡国警察(鸡国有无穷多个警察)来巡逻。
每个警察巡逻的时间长度都为 t 秒。当老鹰来袭击的时刻至少要有 x 名警察才能抵御老鹰的袭击。另外国王派遣警察有两个原则:
(1)每个时刻最多只能派遣一名警察。在第 0 秒时刻及第 0 秒之前的时刻(鸡国有负数时刻)也可以事先准备派遣警察,但每个时刻最多也只能派遣一名警察。
(2)延迟 1 秒执行巡逻任务。第 i 秒时刻派遣的警察,在第 i+1 到 i+t 秒时刻执行巡逻任务。
为帮助国王节省开支,请帮忙计算至少需要派遣多少名警察才能保证鸡国小鸡不被老鹰抓走?
输入
输入共 2 行。
第 1 行输入三个整数 n,t,x,分别表示老鹰总共袭击次数,每个警察巡逻的时间长度为,以及某个时刻能抵挡住老鹰袭击的最少警察数量。
第 2 行 n 个严格升序排列的正整数 t i (1≤i≤n),表示第 t i 秒时刻老鹰会发动袭击。
输出
输出 1 行一个整数,表示总共至少需要派遣多少个警察才能抵御老鹰的 n 次袭击,如果出现无法抵御老鹰的袭击时,输出“-1”(不包含双引号)。
样例输入
3 3 3
2 3 4
样例输出
5
题目大意 :
找到重叠区间 删去重复的部分 得到最终结果;
枚举每个时间点,当执勤时间t小于警察数x时,小j 没有生还的可能,
每个时间点都有一个大小为t的区间,从区间中找到x个点(不包括自身),t大于x,
怎么找重复区间呢?
第一个点需要x个警察,不妨把x个点看做连续的点,这样可以尽量照顾后边的点
第一个点和第二个点之间距离如果大于时间t,第二个点就会像第一个点一样 成为孤立的点,若小于t则出现重复区间
第一个点前边一定有x个连续的点,从第二个点开始,找出与第一个点的重复点的个数,用x减掉,就是除去第一个点的
第二个点前连续点的个数, 具体细节看代码
枚举完毕,题就解决了;
#include<iostream>//聪明的张大帅
using namespace std;
int main()
{
int n,t,x,a[50000];
while(cin>>n>>t>>x)
{
if(t<x)
{
cout<<"-1"<<endl;
break;
}
int i,b=x,c,d,sum=x;
for(i=0;i<n;i++)
cin>>a[i];
for(i=1;i<n;i++)
{
c=t-(a[i]-a[i-1]);
if(c<=0)
{
sum+=x;
continue;
}
if(b>c)
{
sum+=x-c;
if(x-c<a[i]-a[i-1])
b=x-c;
else
b=b+x-c;
}
else {
sum+=x-b;
if(x-b<a[i]-a[i-1])
b=x-b;
else
b=b+x-b;
}
}
cout<<sum<<endl;
}
return 0;
}