Educational Codeforces Round 33 (Rated for Div. 2) D. Credit Card

来源:互联网 发布:淘宝阿迪达斯打假 编辑:程序博客网 时间:2024/06/05 18:07

题意:

看了好久才明白==

给定n个数ai,是n天银行卡存钱取钱的变化(正数存钱,负数取钱),

当ai = 0 时,查询账户余额,这个人不想在查询的时候看到他的账户余额是负数,所以之前的每一天它可以 另外手动 往里面存钱,

问 最少的手动存钱次数,


思路:

首先,用 now 表示当前银行账户,每次跟 最高额度d 比较,可确定答案是否为 -1;


当ai = 0 的时候,如果now < 0,为了保证在之前的某天不会超出额度,所以在 i 的前一天存就是了,,可以存的 额度是 (-now)~  d;

为了尽可能不让之后的某一天额度超限,我们先存(-now),让当前余额为 0元,这时候,再用 (now_)再存还可以再存的最大数额,

每次(now_)要更新,保证再加上(now_)都不会超额度,,这样再次遇到 ai = 0&&now < 0 的时候,我们可以用 (now_)来调节,看是都需要在重新的手动存款


这样扫一边就行了



#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<cmath>#include<set>#include<queue>#include<stack>#include<map>#define PI acos(-1.0)#define in freopen("in.txt", "r", stdin)#define out freopen("out.txt", "w", stdout)#define kuaidian ios::sync_with_stdio(0);using namespace std;typedef long long ll;typedef unsigned long long ull;const int maxn = 1e5, maxd = 1e8;const ll mod = 1e9 + 7;const int INF = 0x7f7f7f7f;int n, d;int a[maxn];int main() {    scanf("%d %d", &n, &d);    for(int i = 0; i < n; ++i) {        scanf("%d", &a[i]);    }    int ans = 0, now = 0, now_ = 0, flag = 0;    for(int i = 0; i < n; ++i) {        if(a[i] == 0 ) {            if(now+now_ < 0 ) { ans++; now = 0; now_ = d;}            else if(now < 0) { int t = now; now = 0; now_ += t; }        }        now += a[i];        now_ = min(now_, d-now) ;        if(now > d) { flag = 1; break; }    }    if(flag) puts("-1");    else printf("%d", ans);    return 0;}


原创粉丝点击