HD-OJ-2141:Can you find it?

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;
}

注意

  1. 这里的Ai不是A*i,而是A中的第i个元素。题意是对于输入的每一个X,判断是否能够
    “从a[]中找到一个元素Ai,从b[]中找到一个元素Bi,从c[]中找到一个元素Ci”,满足等式:Ai+Bj+Ck=X ==> Ai+Bj=X-Ck
  2. 思路:二分算法:典型的二分搜索,先A、B求和并排序,然后二分搜索a+b=x-c

猜你喜欢

转载自blog.csdn.net/Louie_min/article/details/106608570
今日推荐