题解 P6013 【压岁钱】

0
10

月赛\(\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;
} 

<

发布回复

请输入评论!
请输入你的名字