CF 1077C

好久没做题了,bug百出,惭愧惭愧

题目大意是,给一个数组,问删除哪些元素,使得剩下的元素中,存在一个等于其他所有元素之和
数组大小20w,元素为正整数,小于100w

由于都是正数,所以很简单,目标即

a i a j = 2 a k \sum{a_i}-a_j=2*a_k
其中要求j != k
第一步,求出 a i \sum{a_i}
然后枚举j,那么怎么判断是否存在k呢
一开始使用一个记录数组t,记录下所有的 2 a k 2*a_k 有哪些能取到
那么怎么保证j和k不重复呢,在记录t时,如果只有一个 a k a_k ,则记t为k,否则,记为-1,当为-1的时候,不管删哪一个,都会存在另一个能取,就可以不用管,反之,如果不为-1,则要判断是否相同,若相同,则不合法。

然后还要考虑边界情况,为什么m >3000000就可以直接退出呢?留给读者思考
如果不退出,在后面的t[m-a[i]]的时候很容易出现越界错误

代码如下

#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
int n, m;
int a[250000];
int t[3100000];
int Ans;
int main() {
	scanf("%d", &n);
	m = 0;
	for (int i = 0; i < n; ++i) {
		scanf("%d", &a[i]);
		m += a[i];
		if (t[2 * a[i]] == 0)
			t[2 * a[i]] = i+1;
		else
			t[2 * a[i]] = -1;
		if (m > 3000000) {
			printf("0");
			return 0;
		}
	}
	Ans = 0;
	for (int i = 0; i < n; ++i) {
		if (t[m - a[i]] != 0 && t[m-a[i]] != i+1)
			Ans++;
	}
	printf("%d\n", Ans);
	for (int i = 0; i < n; ++i) {
		if (t[m - a[i]] != 0 && t[m - a[i]] != i + 1)
			printf("%d ", i+1);
	}
	return 0;

猜你喜欢

转载自blog.csdn.net/u012397583/article/details/84583410