hdu 2141 Can you find it?

Can you find it?

Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/10000 K (Java/Others)
Total Submission(s): 8118    Accepted Submission(s): 2124


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
 
//这个题开始用普通方法不断剪枝,开始是各种wa,然后就是tle
//后来看到别人合并两个数组,然后再对这个数组二分,这种方法优化了不少
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[1000],b[1000],ab[400000],c[1000];
int main()
{
      int A,B,C,n,i,j,k,ans=1,x;
      while(scanf("%d %d %d",&A,&B,&C)!=EOF)
      {
           k=0;
           memset(a,0,sizeof(a));
           memset(b,0,sizeof(b));
           memset(c,0,sizeof(c));
           memset(ab,0,sizeof(ab));
           for(i=0;i<A;i++)
           scanf("%d",&a[i]);
           for(i=0;i<B;i++)
           scanf("%d",&b[i]);
           for(i=0;i<C;i++)
           scanf("%d",&c[i]);
           for(i=0;i<A;i++)//合并a,b数组
             for(j=0;j<B;j++)
             ab[k++]=a[i]+b[j];
             sort(ab,ab+k);//对合并后的数组排序
             scanf("%d",&n);
             printf("Case %d:
",ans++);
             while(n--)
             {
                  scanf("%d",&x);
                  int l,r,mid,flag=0,t;
                  for(i=0;i<C;i++)
                  {
                       l=0;r=A*B;
                       while(l<=r)//二分
                       {
                            mid=(l+r)/2;
                            if((ab[mid]+c[i])>x)//这里很奇怪如果这样写 if(ab[mid]+c[i]>x)也就是不加括号就WA了
                            r=mid-1;
                            else if((ab[mid]+c[i])==x)//找到了就直接跳出了
                            {
                              flag=1;
                                 break;
                            }
                            else
                            l=mid+1;
                       }
                       if(flag)
                       {
                            printf("YES
");
                             break;
                       }

                  }
                  if(i==C)
                  printf("NO
");
             }



      }
     return 0;
}
原文地址:https://www.cnblogs.com/llei1573/p/3228770.html