AcWing 4908. 饥饿的牛

178 阅读2分钟

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;
}