给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No"。
Input
第1行,1个数N,N为数组的长度(4 <= N <= 1000)
第2 - N + 1行:Aii(-10^9 <= Aii <= 10^9)
Output
如果可以选出4个数,使得他们的和为0,则输出"Yes",否则输出"No"。
Sample Input
5 -1 1 -5 2 4
Sample Output
Yes
解题思路:二分思想,但是四个数只有一个可以二分,所以就要把4个数变成两个,把任意两个数结合,存上两个数的下标,然后就变成2个数匹配两个数,就可以用二分,需要解决的就是不能让这四个数一样
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int i,j,sum;
}b[1000009];
int a[1009],num;
int erfen(int I,long long int x,int l,int r)
{
while(l<=r)
{
int mid=(l+r)/2;
if(b[mid].sum==x)
{
int L=mid,R=mid,flag=0;
while(b[L].sum==x&&L>=1)
{
if(b[L].i!=b[I].i&&b[L].i!=b[I].j&&b[L].j!=b[I].i&&b[L].j!=b[I].j)
{
flag=1;
break;
}
L--;
}
while(b[R].sum==x&&R<=num)
{
if(b[R].i!=b[I].i&&b[R].i!=b[I].j&&b[R].j!=b[I].i&&b[R].j!=b[I].j)
{
flag=1;
break;
}
R++;
}
if(flag)
return 1;
else return 0;
}
else if(b[mid].sum<x)
{
l=mid+1;
}
else
{
r=mid-1;
}
}
return 0;
}
int cmp(node x,node y)
{
return x.sum<y.sum;
}
int main()
{
int n,i,j;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
num=0;
for(i=1; i<=n; i++)
{
for(j=i+1; j<=n; j++)
{
b[++num].sum=a[i]+a[j];
b[num].i=i;
b[num].j=j;
}
}
sort(b+1,b+1+num,cmp);
int flag=0;
for(i=1; i<=num; i++)
{
if(erfen(i,-1*b[i].sum,i+1,num))
{
flag=1;
break;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
return 0;
}