原题链接:AcWing 4908.饥饿的牛
题目来源:夏季每日一题2023
贝茜是一头饥饿的牛。
每天晚上,如果牛棚中还有干草的话,贝茜都会吃掉其中的一捆。
初始时,牛棚中没有干草。
为了让贝茜不被饿死,农夫约翰制定了 N
个给贝茜送干草的计划。
其中第 i
个计划是在第 di
天的白天给贝茜送去 bi
捆干草。
这些计划互不冲突,保证 1≤d1<d2<…<dN≤T
。
请你计算,贝茜在第 1∼T 天中有多少天有干草吃。
输入格式
第一行包含两个整数 N
和 T
。
接下来 N
行,每行包含两个整数 di
, bi
。
输出格式
输出贝茜在第 1∼T 天中有干草吃的天数。
数据范围
- 1≤N≤105 ,
- 1≤T≤1014 ,
- 1≤di≤1014,
- 1≤bi≤109。
输入样例1:
1 5
1 2
输出样例1:
2
样例1解释
两捆干草在第 1 天早上被送到了牛棚,所以贝茜第 1,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 天都有干草吃。
方法一:枚举
思路:
- 首先看到1014 这种,肯定要用long long,而且看T的范围那么大,枚举每一天显然是不可能,考虑枚举每个区间
- 对于一个区间来说,能吃到草的有效天数为
min(区间长度,干草数目)
,因此枚举每个区间,将每个区间的有效天数累加即可 - 最后一段不要忘了
C++ 代码实现:
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int n;
ll t;
int main(){
scanf("%d%lld", &n, &t);
ll res = 0, last = 0, cur = 0; // res结果 last上一区间右端点 cur当前干草数目
for(int i = 1; i <= n; i ++ ){
ll d, b;
scanf("%lld%lld", &d, &b);
ll len = d - 1 - last; // [last+1, d-1]区间的长度
ll days = min(cur, len); // 有效天数应该为区间长度和当前干草的最小值
res += days;
// 更新cur和last
cur = cur - days + b;
last = d - 1;
}
res += min(cur, t - last); // 扫尾
printf("%lld\n", res);
return 0;
}
复杂度分析:
- 时间复杂度:O(n),循环次数和计划数n有关,105级别,O(n)绰绰有余
- 空间复杂度:O(1),常数个临时变量