AcWing 4908. 饥饿的牛
贝茜是一头饥饿的牛。
每天晚上,如果牛棚中还有干草的话,贝茜都会吃掉其中的一捆。
初始时,牛棚中没有干草。
为了让贝茜不被饿死,农夫约翰制定了 N 个给贝茜送干草的计划。
其中第 i 个计划是在第 di 天的白天给贝茜送去 bi 捆干草。
这些计划互不冲突,保证 1≤d1<d2<…<dN≤T。
请你计算,贝茜在第 1∼T 天中有多少天有干草吃。
输入格式
第一行包含两个整数 N 和 T。
接下来 N 行,每行包含两个整数 di,bi。
输出格式
输出贝茜在第 1∼T 天中有干草吃的天数。
数据范围
1≤N≤10^5,
1≤T≤10^14,
1≤di≤10^14,
1≤bi≤10^9。
输入样例1:
1 5
1 2
输出样例1:
2
样例1解释
两捆干草在第 11 天早上被送到了牛棚,所以贝茜第 1,21,2 天有干草吃。
输入样例2:
2 5
1 2
5 10
输出样例2:
3
样例2解释
两捆干草在第 1 天早上被送到了牛棚,所以贝茜第 1,2 天有干草吃。
10 捆干草在第 5 天早上被送到了牛棚,所以贝茜第 5 天有干草吃。
输入样例3:
2 5
1 10
5 10
输出样例3:
5
10 捆干草在第 1 天早上被送到了牛棚,所以贝茜第 1∼5 天都有干草吃。
C++ 代码
#include <iostream>
using namespace std;
// 这题不用开数组,注意范围记得long long
// 直接用i来记录上一次送草的日期
// di即当前送草日 bi即当前送草日送草捆数
// s保存答案天数 g记录当前草总捆数
// 当我们收到草时,只有两种情况:
// 1.在本次送草之前的某天,草已经吃光(即当前送草日di-上次送草日i >= 草捆数g)
// 2.还没吃光
int main(){
long long n,t,di,bi,s=0,g=0,i=0;
scanf("%lld%lld",&n,&t);
while(n--){
scanf("%lld%lld",&di,&bi);
if(di-i>=g){// 草已吃光
s+=g;// 那么增加天数只能为之前草所够吃的天数g(即之前草的捆数)
g=bi;// 因为之前草已经吃光,所以本次送草之后草数量更新为本次送草数bi
}
else{// 没吃光
s+=di-i;// 增加天数为上次送草到本次送草这段时间内吃的草数
g-=di-i;// 更新草数量
g+=bi; // 加上本次送草数
}
i=di; // 更新上次送草日
}
if((t-i+1)<=g) s+=(t-i+1);// 还没到最后一天,加上剩下够吃的天数即可,注意不要超过t
else s+=g;
printf("%lld",s);
return 0;
}
C 代码
#include <stdio.h>
int main(){
long long n,t,di,bi,s=0,g=0;
scanf("%lld%lld",&n,&t);
long long i=0;
while(n--){
scanf("%lld%lld",&di,&bi);
if(di-i>=g){
s+=g;
g=bi;
}
else{
s+=di-i;
g-=di-i;
g+=bi;
}
i=di;
}
if((t-i+1)<=g) s+=(t-i+1);
else s+=g;
printf("%lld",s);
return 0;
}