传送门:codeforces 893D
题目大意:
有一张信用卡,初始金额为 0. 每天都有交易额 a[i],每天早上可以去银行补充任意金额(正数)的钱,每天晚上需要进行以下操作:
1. a[i]>0 时,往信用卡里存入 a[i] 的钱
2. a[i]<0 时,从信用卡里取出 a[i] 的钱
3. a[i]=0 时,核对信用卡里的钱
要求信用卡里的钱数不得超过上限 d,如果一定超过上限 d 则输出 -1 。每次核对的时候银行卡里的钱不得为负数,问最少需要去银行补充多少次钱。
思路:
先考虑输出 -1 的情况,也就是只满足最低要求的情况下,如果信用卡里的钱还会超过 d,则输出 -1. 注意由于要求每次核对时信用卡里的钱不得为负数,所以每次核对时如果信用卡里的钱为负值,则置为 0.
然后考虑最少去银行补充几次钱。很明显,银行卡里的钱越多,需要补充的次数就越少,最多为上限 d。但是这样又会出现新的问题:如果当前信用卡里的钱为 d,而接下来的交易额为正数的话则就超过上限了,不符合题意。所以,如果信用卡里的钱大于 d 的时候应该将钱置为 d。
代码:
#include<stdio.h>
#include<string.h>
int main()
{
int i,n,d,f,sum,ans,a[100010];
while(~scanf("%d%d",&n,&d))
{
f=sum=0;
for(i=0;i<n;i++)
{ //输入交易额并判断是否会超过上限
scanf("%d",&a[i]);
sum+=a[i];
//如果核对时钱小于 0,则置为 0
if(a[i]==0&&sum<0) sum=0;
if(sum>d) f=1; //超过上限
}
if(f) printf("-1\n");
else
{
ans=sum=0;
for(i=0;i<n;i++)
{ //求最少补充钱的次数
sum+=a[i];
if(sum>d) sum=d; //如果当前钱大于上限则置为 d
if(a[i]==0)
{ //核对
if(sum<0)
{ //如果钱为负数则结果 +1
ans++;
sum=d; //将信用卡内的钱补充到最大
}
}
}
printf("%d\n",ans);
}
}
return 0;
}