题目描述
韭菜是种生命力非常顽强的植物, 当播下种子在第 X 天就能进行第一次收割, 收割完成后重新生长, 再经过 Y 天后又能继续收割, 如果进行施肥则会缩短 W 天的成长时间, 如果已经长大了则不在继续缩短时间, 而且韭菜有个非常大的缺点, 不能过量施肥, 每个成长阶段只能施一次肥,当施肥过多可能会导致韭菜死亡。
小唐的爷爷拥有 1 亩韭菜地, 地里最多能种下 N 颗韭菜, 每次收割韭菜, 每颗韭菜能获得 1 斤, 爷爷的每日的工作安排顺序如下:
- 能收割, 则进行收割
- 需要施肥, 则进行施肥
- 需要播种, 则进行播种。
因为爷爷很容易健忘, 可能会给韭菜过多的施肥, 过多施肥会导致韭菜地的韭菜死亡, 需要当天重新播种。
爷爷已经将韭菜播种完毕, 经过 T 天后, 爷爷能够收获多少斤韭菜呢?
输入格式
输入一行 N、 X 和 Y , 表示韭菜的数量, 韭菜的初次生长日期, 以及再次生长日期
输入一行 T、 M 和 W , 表示天数, 施肥的次数以及缩短的天数
接下来 M 行, 输入 Ai, 表示在第几天施肥。
输出格式
爷爷一共收获多少斤的韭菜。
样例
样例输入
8 4 2
10 4 1
1
2
6
9
样例输出
32
样例解释
第一天: 施肥
第二天: 施肥, 该阶段多次施肥, 重新播种
第六天: 收割, 施肥
第七天: 收割
第九天: 收割, 施肥
第十天: 收割
数据范围
思路分析
注意:此题题目存在歧义(没有明确说明某一天是否可以重复施肥,即同一天是否最多只能施肥一次)。
按理说应该考虑重复施肥,但官方给的标程并没有考虑,并且存在重复施肥的测试数据点。
不过不管是按照哪种题意进行理解,该题解均可胜任,只存在某一行代码的区别,首先先介绍我的理解,即“可以重复施肥”。
由于T <= 1e6
,故我们可以枚举天数。
对于每天,我们可以分别处理 收割、施肥、播种 。
首先处理收割:
用tmp表示离收割还有多少天,则每天的开始,tmp需要减1。且若tmp <= 0
,则说明可以收割,进行收割即可。
tmp--;
if(tmp <= 0){
tmp = y; // tmp初始化为y(因为已经进行了一次收割)
// cnt表示收割的总次数
cnt++; // 收割的次数+1
// flag表示一个生长周期内是否进行过施肥
flag = false; // 新的生长周期开始,flag初始化为false
}
然后处理施肥和播种:
用st数组表示当天是否进行施肥。
if(st[i] == 1){ // 如果当天进行施肥
if(!flag){ // 若当前生长周期内没有施过肥
tmp -= w; // 天数减小w
flag = true; // 标记当前生长周期已经施过肥
}else{
// 若当前生长周期内已经施过肥了,则种子会死亡,会重新播种
tmp = x;
flag = false;
}
}else if(st[i] > 1){
// 若当天不止施肥一次,则种子肯定死亡,会重新播种
tmp = x;
flag = false;
}
时间复杂度O(T)。
接下来说明按照官方的理解(同一天最多只能施肥一次):
ps:由于官方的数据存在“重复施肥”的情况,所以按照我的理解会WA,进行如下修改即可AC官方数据(官方数据如果未修正的话)
只需要把读入数据时统计st[j]
的代码改成st[j] = 1
即可
cin >> n >> x >> y >> t >> m >> w;
for(int i = 0,j;i < m;i++){
cin >> j;
// st[j]++;
st[j] = 1; // 按照官方的理解进行修改
}
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n,x,y;
int t,m,w;
int st[N];
int cnt;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> n >> x >> y >> t >> m >> w;
for(int i = 0,j;i < m;i++){
cin >> j;
st[j]++; // 我的理解
// st[j] = 1; // 官方的理解
}
int tmp = x;
bool flag = false;
for(int i = 1;i <= t;i++){
// 收割
tmp--;
if(tmp <= 0){
cnt++;
tmp = y;
flag = false;
}
// 施肥
if(st[i] == 1){
if(!flag){
tmp -= w;
flag = true;
}else{
// 播种
tmp = x;
flag = false;
}
}else if(st[i] > 1){
// 播种
tmp = x;
flag = false;
}
}
cout << (LL)cnt * n;
return 0;
}