B. Array Cancellation Codeforces Round #668 (Div. 2)

题目链接

B. Array Cancellation

题目

在这里插入图片描述

input

7
4
-3 5 -3 1
2
1 -1
4
-3 2 -3 4
4
-1 1 1 -1
7
-5 7 -6 -4 17 -13 4
6
-1000000000 -1000000000 -1000000000 1000000000 1000000000 1000000000
1
0

output

3
0
4
1
8
3000000000
0

Note

Possible strategy for the first test case:
Do (i=2,j=3) three times (free), a=[−3,2,0,1].
Do (i=2,j=1) two times (pay two coins), a=[−1,0,0,1].
Do (i=4,j=1) one time (pay one coin), a=[0,0,0,0].

题意

给你一个有n个整数的数组,在一次操作中,可以选择两个不同的下标i,j,使ai减一、aj加一;如果i<j则本次操作免费,否则需要一个金币。问最少需要多少金币可以使数组a全部为0.

思路

刚开始我的想法是,从最后往前面遍历,碰到负数,就和前面的整数进行操作,把负数变为0,最后再从前往后把负数加起来就是答案,但是超时了。

后来我发现只要判断到每个数之前剩余多少正数即可。相当于算前缀和,只不过和小于等于0的时候都要标记为0.

TLE代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <utility>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <list>
#include <set>
#include <cstdlib>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 10;
const int N = 10010;
const int INF = 0x3f3f3f3f;
const ll  LNF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 10007;
const double eps = 10e-6;
const double PI = 3.14159265358979323;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
priority_queue<int, vector<int>, less<int> >q;
priority_queue<int, vector<int>, greater<int> >qq;
 
ll a[maxn];
int main () {
	IOS
	int t;
	while (cin >> t) {
		while (t--) {
			int n;
			cin >> n;
			for (int i = 1; i <= n; i++) {
				cin >> a[i];
			}
			for (int i = n; i > 1; i--) {
				if (a[i] < 0) {
					ll len = 0 - a[i];
					for (int j = i - 1; j >= 1; j--) {
						if (a[j] >= len) {
							a[j] -= len;
							a[i] = 0;
							break;
						} else if (a[j] > 0) {
							a[i] += a[j];
							len -= a[j];
							a[j] = 0;
						}
					}
				}
			}
			ll ans = 0;
			for (int i = 1; i <= n; i++){
				if (a[i] < 0){
					ans += abs(a[i]);
				}
			}
			cout << ans << endl;
		}
	}
	return 0;
}

ac代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <utility>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <list>
#include <set>
#include <cstdlib>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 10;
const int N = 10010;
const int INF = 0x3f3f3f3f;
const ll  LNF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 10007;
const double eps = 10e-6;
const double PI = 3.14159265358979323;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
priority_queue<int, vector<int>, less<int> >q;
priority_queue<int, vector<int>, greater<int> >qq;

ll a[maxn];
int main () {
	IOS
	int t;
	while (cin >> t) {
		while (t--) {
			int n;
			cin >> n;
			for (int i = 1; i <= n; i++) {
				cin >> a[i];
			}
			ll ans = 0;
			for (int i = 1; i <= n; i++){
				if (a[i] >= 0){
					ans += a[i];
				}else{
					ll len = 0 - a[i];
					if (ans >= len){
						ans -= len;
					}else{
						ans = 0;
					}
				}
			}
			cout << ans << endl;
		}
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值