简单题-3 无所谓,我会出手
分数 15
全屏浏览题目
切换布局
作者 JMU_ACM
单位 集美大学
题目背景:
2222年,位于地球的某一处,小H像往常一样观测着宇宙的变化,他无意间看到了宇宙深处隐约有恐怖怪异的残影正在不断向地球靠近。
“难道要发生了吗?”,小H小声嘀咕。
传说宇宙不定期会出现可以吞噬地球的红色怪鱼,新闻曾经报道过有人拍摄到了这只红色怪鱼,但在不久后被人证实这些新闻只是利用相机拍出模糊的画面以此在媒体上炒作获得流量,因此大多数人认为这些传说仅仅只是古人的臆造。起初小H也不以为然,但严谨的学术态度让小H对此产生了研究兴趣,他翻阅了大量国内外论文并没有任何收获。正当一筹莫展的时候,小H瞥见了图书馆一本出版于2022年早已残破不堪的古籍《鲹鲴鳢鳏鲼鲯鲗》,如此多鱼触碰到小H敏锐的学术洞察力,于是小H通宵达旦一刻也不敢停歇,当最后一页被合上时,时间已经过去了1天14小时51分钟4秒。
古籍上记载了诸多鱼类,红色怪鱼只是其中一种。从古籍中记载红色怪鱼出现的时间中看不出很明显的规律,但小H断定宇宙一定也存在着某种伪随机数生成器。经过了一番研究,小H得到了一串预测公式,对古籍中记载红色怪鱼出现的时间进行验证后发现这些数据完全符合公式,这意味着小H已经掌握了红色怪鱼吞噬地球的时刻,而下一个时刻正好就是几天后。
题目描述:
小H根据古籍记载红色怪鱼的弱点,研究出了击败红色怪鱼的机器。由于机器系统的复杂性,一天只能建造一台机器,并于建造第二天 0 点启动机器。因为机器运行会受到宇宙中各种力量的影响,机器运行 d 天报废:假设建造机器的时间为第 x 天,那么这台机器将在第 x+d+1 天 0 点以后无法使用。小H不会因为红色怪鱼的到来而停止工作,为了抵御下一只红色怪鱼,他也可以在红色怪鱼到来的当天继续建造新的机器。为了避免误伤无辜,运行中的机器只会在红色怪鱼吞噬地球的时刻产生攻击,至少需要 a 台这样的机器同时攻击才能击败一只红色怪鱼。
小H将研究成果公布以后,媒体纷纷采访小H,每一次他只平淡地留下了一句“无所谓,我会出手”。
几天后,这只红色怪鱼被消灭了,小H也获得了”谁言人族无大帝“的赞誉。小H并没有因此而感到高兴,因为宇宙是一个周期很长的伪随机数生成器,红色怪鱼还会重返地球。小H将接下来 n 只红色怪鱼吞噬地球的时刻告诉了你,以小H求助你的时间为第零天,第 i ( 1≤i≤n) 只红色怪鱼将于第 ti 天吞噬地球,希望你能告诉他是否能击败这 n 只红色怪鱼。如果可以至少需要建造多少台这样的机器才能成功击败红色怪鱼,如果不可以请你也告他这悲伤的事实。
输入格式:
第一行包含三个正整数 n,a,d,分别代表红色怪鱼的数量,击败一只红色怪鱼所需同时工作机器的数量,一台机器的使用寿命。
第 i+1 ( 1≤i≤n ) 行包含一个正整数 ti , 代表第 i 只红色怪鱼吞噬地球的时刻,数据保证 ti 序列为升序。
输出格式:
第一行输出一个字符串,代表小H是否能击败 n 只红色怪鱼,如果能请输出 Yes
(注意大小写),如果不能请输出 No
(注意大小写)。
若能击败 n 只红色怪鱼,在第二行输出一个整数,代表至少需要建造机器的数量。
输入样例1:
4 1 9
1
9
19
810
输出样例1:
Yes
3
小H可以在第0、18、809天建造机器,第一台机器打败了前两只,第二台机器打败了第三只,第三台机器打败了第四只。
输出样例2:
1 2 3
1
输出样例2:
No
第一只怪鱼在第1天出现,小H最多只能在第0天建造一台机器,但是需要2台机器同时工作才能击败红色怪鱼,因此无法击败怪鱼。
数据范围:
对于30%的数据,1≤n≤2×103,1≤a≤10,1≤d≤5000,1≤ti≤2×104
对于70%的数据,1≤n≤3×104,1≤a≤50,1≤d≤5000,1≤ti≤3×105
对于100%的数据,1≤n≤105,1≤a≤300,1≤d≤5000,1≤ti≤106
做题思路:
首先看完题目,我们一开始就需要判断可以可以击败怪物,如果第一次怪物生成的天数t1减去做机器需要的时间即t1-a<0就无法击败怪物,直接输出即可 如果一次性需要的机器d小于机器的寿命也无法击败怪物(因为在机器运行期间我们可以做机器,所以只要d>a 可以提前做击败怪物)
所以在题目一开始就先判断可不可以击败怪物
if(t<a||d<a)
cout<<"No";
ok,在排除不能的情况之后,就要考虑需要的机器数量了,还有在第二个及之后的怪物来到之后,哪几个机器还有效,哪几个无效了,如果无效了,就要重新制造机器了
所以我们这边可以考虑用队列来完成这个判断 ,把每次制造的机器的天数依次导入队列,然后判断在判断在怪物来袭的天数是不是在机器的有效期之内,如果不行就舍弃这个机器
queue<int> aa;
while(!aa.empty()&&aa.front()+d<t){//在a.front()+d之间是这个机器有效的天数
aa.pop();
}//有效留着
不行的机器舍弃之后,计算需要重新制作的机器,在导入队列
int addday = a-aa.size();
for(int j = t-addday;j<t;j++){
aa.push(j);
count++;
}
整体实现代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,a,d,t;
int count = 0;
cin>>n>>a>>d>>t;
if(t<a||d<a)
cout<<"No";
else {
queue<int> aa;
for(int j = t-a;j<t;j++){
aa.push(j);
count++;//把需要的机器数量读入
}
for(int i = 0;i<n-1;i++){
cin>>t;
while(!aa.empty()&&aa.front()+d<t){
aa.pop();
}//有效留着
int addday = a-aa.size();
for(int j = t-addday;j<t;j++){
aa.push(j);
count++;
}
// cout<<count<<endl;
}
cout<<"Yes"<<endl<<count;
}
}
运行截图: