给出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
首先说一下题的思路,两两配对,用结构体存放两个数的和以及这两个数的坐标,再判断只要和为0并且坐标不同就可以
结构体里用二分用到了友元函数的知识(谭浩强牛逼)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=105;
const int mod=7;
ll N,A[1005],ans;
struct Why
{
ll sum;
ll x;
ll y;
friend bool operator <( Why a, Why b ) // 这就是重点了,需要手动在结构体里添加小于号的重载
{
return a.sum<b.sum;
}
}H[1005*1005];
bool cmp(Why a,Why b)
{
return a.sum<b.sum;
}
int main()
{
ios::sync_with_stdio(false);
cin>>N;
for(int i=0;i<N;i++)
cin>>A[i];
for(int i=0;i<N;i++)
for(int j=i+1;j<N;j++)
{
H[ans].sum=A[i]+A[j]; //求两两的和以及坐标
H[ans].x=i;
H[ans].y=j;
ans++;
}
sort(H,H+ans,cmp);
ll t;
for(int i=0;i<N;i++)
for(int j=i+1;j<N;j++)
{
t=A[i]+A[j];
Why k;
k.sum=0-t; // 对k赋值
int L=lower_bound(H,H+ans,k)-H; //这里二分查的是K这个结构体!不是数值
if(H[L].sum+t==0&&H[L].x!=i&&H[L].x!=j&&H[L].y!=i&&H[L].y!=j)
{
cout<<"Yes"<<endl;
return 0;
}
}
cout<<"No"<<endl;
return 0;
}