之前做过两个数 三个数和为K的情况,两个数字可以用指针的方法,而三个数字就需要用二分了。
此题也是一样。将4个数字和位K的情况,归为两个数字和K的情况,
做法为: 将数字两两相加存入数组,并且记录下是由第几个数字和第几个数字相加而来。
这样就标称了两个数字的的情况。其他博客里写了种指针的情况,其实就是按照两个数字和为K的情况下指针的做法。自然会比二分快一些
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=1000000+5;
typedef long long ll;
ll a[maxn];
struct node
{
int x,y;
ll sum;
}s[maxn];
int vis[maxn];
int n; int cnt=0;
int judge(int aim,int l,ll x)
{
int r=cnt;
ll mid;
while(l<=r)
{
mid=(l+r)/2;
if(s[mid].sum==x &&s[mid].x!=s[aim].x &&s[mid].x!=s[aim].y &&s[mid].y!=s[aim].x &&s[mid].y!=s[aim].y)
{
return mid;
}
else
{
if(s[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()
{
cin>>n;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
{
for(int j=1+i;j<=n;j++)
{
s[++cnt].sum=a[i]+a[j],s[cnt].x=i,s[cnt].y=j;
}
}
sort(s+1,s+1+cnt,cmp);
int flag=0;
for(int i=1;!flag&&i<=cnt;i++)
{
ll res=s[i].sum;
if(judge(i,i+1,-res))
{
flag=1;
}
}
if(!flag)
{
cout<<"NO"<<endl;
}
else
cout<<"YES"<<endl;
return 0;
}