codeforces Round #668 (Div. 2) 1405B Array Cancellation

题目链接

在这里插入图片描述

题目翻译:

给你一个数组a,包含n个整数,并且a1 + a2 + … + an = 0 。
在一次操作中,你可以选择两个不同的下标ij(1<=i,j<=n),将ai减一,aj加一。如果i<j,这个操作就是免费的,否则此操作花费一枚硬币。
问为了让所有的元素都变成0最少需要花费多少枚硬币?

解题思路:

我们可以统计未被免费操作掉的正数的和,保存到变量ans中。显然ans就是最后需要花费的硬币枚数。遍历每个数,当出现正数时,直接加入ans中;当出现负数时,说明之前累加的正数现在可以被免费操作掉,因此ans=ans+a[i](因为a[i]是负数,所以是+),注意如果ans变成负数,要让ans=0,表示未被免费操作掉的正数的和为0,可以直接写成ans=max(0LL,ans+a[i]);

代码:
#include<iostream>
#include<cmath>
using namespace std;
const int N = 100010;
int a[N],t,n;
int main(){
    
    
	freopen("1.txt","r",stdin);
	cin>>t;
	while(t--){
    
    
		cin>>n;
		long long ans=0;
		for(int i=0;i<n;i++){
    
    
			cin>>a[i];
			ans=max(0LL,ans+a[i]); 
		}
		cout<<ans<<endl;
	}
	return 0;
}
总结:

想不出怎么写就把测试样例都动手模拟一遍,总会找到规律。

猜你喜欢

转载自blog.csdn.net/lmmmmmmmmmmmmmmm/article/details/108463335