给出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
把每两个数的和存下来,并且还要存下每个数的下标,防止选的数字重复,然后直接二分找就可以了。
一开始TLE了两次,还以为是算法写的有问题,后来发现数组开小了。。。51Nod对于数组开小不是报RE,而是报TLE。。。
求和的数组大概开到10^6吧。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long int LL;
const int MAXL(1e6);
const int MAX(0x3f3f3f3f);
int a[MAXL+50];
int ans[MAXL+50];
struct node
{
int index1,index2;//组成和的两个数字的下标
int data;
}s[MAXL+50];
bool cmp(struct node p,struct node q)
{
return p.data<q.data;
}
bool judge(struct node p,struct node q)//判断下标
{
if(p.index1==q.index1)
return false;
if(p.index1==q.index2)
return false;
if(p.index2==q.index1)
return false;
if(p.index2==q.index2)
return false;
return true;
}
int Binary_search(int left,int right,int target)
{
int index=0;
while(left<=right)
{
int mid=(left+right)/2;
if(s[mid].data<=target)
{
left=mid+1;
index=mid;
}
else
right=mid-1;
}
return s[index].data==target?index:-1;
}
int main()
{
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
int len=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
s[len].index1=i;
s[len].index2=j;
s[len++].data=a[i]+a[j];
}
}
sort(s,s+len,cmp);
for(int i=0;s[i].data<=0;i++)//终止条件,data<=0,可以节省很多时间
{
int x=fabs(s[i].data);
int index=Binary_search(i,len-1,x);
if(index==-1)
continue;
if(judge(s[i],s[index])==true)
{
cout<<"Yes"<<endl;
return 0;
}
}
cout<<"No"<<endl;
}