三数和为零

题目

 三数和为零

Time Limit: 2 Sec   Memory Limit: 128 MB
Submit: 911   Solved: 72
[ Submit][ Status][ Web Board]

Description

在序列a 1,a 2,...,a n(n>=3)中,是否存在(0<i<j<k<=n)满足a i+a j+a k=0?

Input

多组数据,第一行给出数据组数T
每组数据第一行有一个整数n(3<=n<=2000),表示序列的长度
第二行有n个由空格隔开的整数,表示序列{a n},(|a i|<=10 9)

Output

对每组数据,若存在,输出Yes,否则输出No

Sample Input

2
3
1 2 3
3
-1 3 -2

Sample Output

No
Yes

思路

这题跟《挑战》上的最开始的抽签那题是一样的。。。只是那题是每个数可重复利用,这里不能重复利用,即无放回抽签

思路为,枚举三个数(暴力)的复杂度为O(n^3),但我们稍微变形一下暴力的公式,变为只枚举两个数,看两数和的相反数是否在数列中,这里只需在枚举的同时判断是否有重复即可,复杂度为O(n^2)。


细节

判重,若每次枚举都话O(n)的时间去判断是否重复的话,这个算法的复杂度还会是O(n^3)。可用数据结构存储,用空姐换时间。。。

代码


#include <bits/stdc++.h>

using namespace std;
#define MAX_N 2010
int num[MAX_N];
int N;
void solve();
map<int, int> tMap;

int main()
{
    int T;
    scanf("%d", &T);
    while (T--) {
		scanf("%d", &N);
		tMap.clear();
		for (int i = 0; i < N; i++) {
			scanf("%d", &num[i]);
			tMap[num[i]]++;
		}
		solve();
    }
    return 0;
}

void solve() {
	sort(num, num+N);
	for (int a = 0; a < N; a++) {
		for (int b = 0; b < N; b++) {
			if (a == b) continue;
			if (binary_search(num, num+N, -(num[a]+num[b]) ) ) {
				if (-(num[a]+num[b]) == num[a] ) {
//					if (count(num, num+N, num[a]) < 2) {
					if (tMap[num[a]] < 2) {
						puts("No");
						return;
					}
				}
				if (-(num[a]+num[b]) == num[b] ) {
					if (tMap[num[b]] < 2) {
						puts("No");
						return;
					}
				}
				puts("Yes");
				return;
			}
		}
	}
	puts("No");
	return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值