思路:
由题知,需要寻找数满足a+b+c+d=m,采用二分查找法。检查是否有c和d使得c+d=m-a-b,这种情况要预先枚举出c+d所得的n*n个数字并排好序,再利用二分搜索。
记所要查找的值m-a-b为x,预先把数组排好序,然后看数组中央的数字,可知
如果它比x小,x只可能在它的后面半段;
如果它比x大, x只可能在它的前面半段。
如果再将上述方法运用在已经减半的x的存在区间上,x的存在区间就变成了初始的1/4,这样反复操作就可以不断缩小x的存在区间,最终可以确定x存在与否。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 10
int i,n,m,a[MAX],aa[MAX*MAX];
bool binary(int x)
{
int small=0,big=n-1; //从第一个和最后一个数开始
while(big>=small)
{
int i=(small+big)/2; //中间数
if(aa[i]==x)
return true; //找到该数
else if(aa[i]<x) //定位后半部分
small=i+1;
else //定位前半部分
big=i-1;
}
return false;
}
int solve()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
aa[i*n+j]=a[i]+a[j]; //建立新数组保存两数之和
sort(aa,aa+n*n);
int f=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(binary(m-a[i]-a[j]))
f=1; //找到符合条件的组合
}
}
return f;
}
int main() {
cin>>n>>m;
for(i=0;i<n;i++)
cin>>a[i];
int a=solve();
if(a)
cout<<"yes";
else
cout<<"no";
return 0;
}