题解 P6013 【压岁钱】

月赛\(\text{Div2T1}\),窝唯一一道\(\text{AC}\)的题(我太菜啦!)


\(\text{solution:}\)

根据题面,显然三个操作对应三种情况,我们发现每次这三种操作均不涉及前面的数,所以考虑边读边做(暂时不用考虑操作三,它是此题中唯一一个难点,待会再说)

该数据范围在\(\text{int}\)范围内。使用变量\(\text{money}\)记录当前的压岁钱的多少,\(\text{ans}\)记录钱不够花的事件数。至此,我们已经可以完美解决前两个操作。核心代码如下。

for(int i=1;i<=m;i++){
    money+=f[i];
    cin>>t;
    if(t==1){
        cin>>a;
        money+=a;
    }
    else if(t==2){
        cin>>a;
        if(money<a)ans++;
        else money-=a;
    }
}

接下来单独考虑操作三。一种显而易见的思路:用一个数组,每当进行操作三时,该数组下标为 \(b\) 的地方值加上 \(a\) ,注意!是加上 \(a\) 而不是赋值为 \(a\) ,因为注意到数据有可能出现多个 \(a\) 封印在同一事件的情况。同时,在每次循环时最前面让\(\text{ans}\)加上此数组下标为 \(i\) 的值。当没有压岁钱封印在事件 \(i\) 时加上的是0,反之,加上的则是那个数组下标为 \(i\) ,即,在 \(i\) 事件解封的压岁钱数。

至此,思路整理完毕。完整(\(\text{AC}\))代码:

#include <iostream>
#include <cstdio>

using namespace std;

unsigned long long m,t,a,b,money,ans,f[10000001];

int main(){
    cin>>m;
    for(int i=1;i<=m;i++){
        money+=f[i];
        cin>>t;
        if(t==1){
            cin>>a;
            money+=a;
        }
        else if(t==2){
            cin>>a;
            if(money<a)ans++;
            else money-=a;
        }
        else if(t==3){
            cin>>a>>b;
            money-=a;
            f[b]+=a; //有可能多个压岁钱封印在同一时刻 
        }
    }
    cout<<ans<<endl;
    return 0;
} 

猜你喜欢

转载自www.cnblogs.com/Nicest1919/p/12308502.html
今日推荐