HD-OJ-2141:Can you find it?
Can you find it?
Problem Description
Give you three sequences of numbers A, B, C, then we give you a number X. Now you need to calculate if you can find the three numbers Ai, Bj, Ck, which satisfy the formula Ai+Bj+Ck = X.
Input
There are many cases. Every data case is described as followed: In the first line there are three integers L, N, M, in the second line there are L integers represent the sequence A, in the third line there are N integers represent the sequences B, in the forth line there are M integers represent the sequence C. In the fifth line there is an integer S represents there are S integers X to be calculated. 1<=L, N, M<=500, 1<=S<=1000. all the integers are 32-integers.
Output
For each case, firstly you have to print the case number as the form “Case d:”, then for the S queries, you calculate if the formula can be satisfied or not. If satisfied, you print “YES”, otherwise print “NO”.
Sample Input
3 3 3
1 2 3
1 2 3
1 2 3
3
1
4
10
Sample Output
Case 1:
NO
YES
NO
#include<stdio.h>
#include<stdlib.h>
#define MAXN 510
int a[MAXN],b[MAXN],c[MAXN],ab[MAXN*MAXN];
int L,N,M,k; //k为ab[]中有效数据元素的个数,即右边界
//比较器
int cmp(const void *a, const void *b)
{
return *(int*)a - *(int*)b;
}
//二分查找: 在ab[]中查找y
int judge(int y)
{
int left=0,right=k;
while( left<right )
{
int mid=left+(right-left)/2;
if(ab[mid]<y)//x落在右半区
left=mid+1;
else if(ab[mid]>y)//左半区
right=mid; //如果用mid-1是个坑
else//相等
return 1;
}
return 0;
}
int main()
{
//freopen("in.txt","r",stdin);
int cas=1;
while( ~scanf("%d%d%d",&L,&N,&M) )
{
printf("Case %d:\n",cas++);
//输入A序列
for(int i=0;i<L;i++)
scanf("%d",&a[i]);
//输入B序列
for(int i=0;i<N;i++)
scanf("%d",&b[i]);
//输入C序列
for(int i=0;i<M;i++)
scanf("%d",&c[i]);
//造二分序列:把A、B中的所有元素进行求和,结果存入数组ab[],排序
k=0;//求和结果元素在ab[]中的序号
for(int i=0;i<L;i++) //A序列
for(int j=0;j<N;j++) //B序列
{
ab[k++]=a[i]+b[j];
}
qsort(ab,k,sizeof(ab[0]),cmp);//对ab[]排序
int s,x;
scanf("%d",&s);
while(s--)
{
scanf("%d",&x);
int flag=0;
for(int i=0;i<M;i++)
{
int y = x-c[i]; //y = x-c
if( judge(y) ) //到ab[]序列中二分查找y,若存在则返回1,否则返回0
{
flag=1;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}
注意
- 这里的Ai不是A*i,而是A中的第i个元素。题意是对于输入的每一个X,判断是否能够
“从a[]中找到一个元素Ai,从b[]中找到一个元素Bi,从c[]中找到一个元素Ci”,满足等式:Ai+Bj+Ck=X ==> Ai+Bj=X-Ck - 思路:二分算法:典型的二分搜索,先A、B求和并排序,然后二分搜索a+b=x-c