题意:
给定三个集合A[ l ] , B [ m ] ,C [ n ],a , b , c 分属于ABC三个集合,给出一个数 x, 问是否在这三个集合中找到满足a+b+c=x;如能找到,输出YES,否则 NO;
分析: 很显然用暴力查找的话,会超时,考虑用二分查找,来降低时间复杂度
注意点:由于给定的数据范围int32,但是在程序处理过程中,可能会有超出Int32位,所以用__int64,还需要考虑的就是存储空间的限制,如果是三个循环处理组合相加的话,则数组要开到500^3,坑定会MLE;可以考虑将a+b+c=x ——》a+b=x-c ;来处理;
原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=2141
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 510
#define MAXN 250010
__int64 a[MAXN],A[N],C[N];
bool find(__int64 x,__int64 L,__int64 R)
{
__int64 mid,left=L,right=R-1;
while(left<=right)
{
mid=(left+right)>>1;
if(a[mid]==x)
return true;
else{
if(a[mid]>x)
right=mid-1;
if(a[mid]<x)
left=mid+1;
}
}
return false;
}
int main()
{
int l,n,m,s;
__int64 x,temp,t=1;
while(~scanf("%d %d %d",&l,&n,&m))
{
memset(a,0,sizeof(a));
__int64 num=0;
for(int i=0;i<l;i++)
scanf("%I64d",&A[i]);
for(int i=0;i<n;i++){
scanf("%I64d",&temp);
for(int j=0;j<l;j++)
a[num++]=A[j]+temp;
}
for(int i=0;i<m;i++)
scanf("%I64d",&C[i]);
printf("Case %I64d:\n",t++);
sort(a,a+num);
scanf("%d",&s);
for(int k=0;k<s;k++)
{
scanf("%I64d",&x);
int flag=0;
for(int i=0;i<m;i++){
__int64 t=x-C[i];
if(find(t,0,num)){
flag=1;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}