基准时间限制:1 秒 空间限制:131072 KB 分值: 20
难度:3级算法题
给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No"。
Input
第1行,1个数N,N为数组的长度(4 <= N <= 1000) 第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9)
Output
如果可以选出4个数,使得他们的和为0,则输出"Yes",否则输出"No"。
Input示例
5 -1 1 -5 2 4
Output示例
Yes
思路:对于 a[i],先求出 a[0]->a[i-1]的所有两两组合,保存在set中。在求 a[i]->a[n-1]中两两组合中二分查找是否与set中的元素和为0。 直接看来时间复杂度是 O(n^3*lg(n)),但是从 a[n] 从 1开始遍历,只要每次将 a[0->n-2] 分别于 a[n-1]两两组合存入 set,这样就可以把a[0]->a[i-1]的所有两两组合都求出来, 在将 a[i+1->n-1]分别于 a[i]两两组合,这样 也可以遍历出 a[i]->a[n-1]中所有的两两组合,这样时间复杂度就优化为 O(n*2*lg(n))
Code:
#include<iostream>
#include<set>
using namespace std;
const int MAX_N=1005;
int n,a[MAX_N];
set<int> cc;
int main()
{
cin>>n;
for(int i=0;i<n;++i)
cin>>a[i];
bool boo=false;
for(int i=1;i<n&&boo==false;++i)
{
for(int j=0;j<i-1;++j)
cc.insert(a[i-1]+a[j]);
for(int j=i+1;j<n&&boo==false;++j)
if(cc.find(-a[i]-a[j])!=cc.end()) boo=true;
}
if(boo==true) cout<<"Yes"<<endl;
else cout<<"NO"<<endl;
return 0;
}