C - Can you find it? HDU 2141

C - Can you find it?

Time Limit:3000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
Submit

Status
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


  1. 题意:给三个数列,再给你一个数,问你能不能三个数组中各选一个数,是他们之和与这个数相等。’
  2. 思路:用三个循明显超时,可选二分法降低时间复杂度,其实就是要将循环的层数减少,里面判断的次数减少。方法就是查找之前对数组进行处理,使其有序,并且将多个数组转化成两个或一个数组,用空间来换取时间。
  3. 失误:开始没思路,数据太多,顺序弄错不少。
  4. 代码如下:
#include<iostream>
#include<cstdio> 
#include<algorithm>
using namespace std;

const int MAXN=510;
int a[MAXN],b[MAXN],c[MAXN],sum[MAXN*MAXN]; 
int main()
{
    int L,M,N,i,j,flag,s,right,left,mid,k=0,x,freq,S;
    while(~scanf("%d%d%d",&L,&N,&M))
    {
        for(i=1;i<=L;++i)
        {
            scanf("%d",&a[i]);
        }
        freq=0;
        for(i=1;i<=N;++i)
        {
            scanf("%d",&b[i]);
            for(j=1;j<=L;++j)
            {
                sum[++freq]=b[i]+a[j];//二分查找一般一或两个数组  多了转化成两个 
            }
        }
        for(i=1;i<=M;++i)
        {
            scanf("%d",&c[i]);
        }
        sort(sum+1,sum+N*L+1);
        scanf("%d",&S);
        printf("Case %d:\n",++k);
        while(S--)
        {
            scanf("%d",&x);
            flag=0;
            for(i=1;i<=M;++i)
            {
                 left=1,right=N*L;
                 while(right>=left)//二分法呈指数形式降低计算量 再大的数也计算不过几十次 
                {
                    mid=left+right>>1; 
                    s=c[i]+sum[mid];
                    if(s==x) 
                    {
                          flag=1;
                          break;
                    } 
                    else
                    if(s>x)
                    {
                        right=mid-1;
                     } 
                     else
                     {
                        left=mid+1;
                     }
                }
               if(flag)
               {
                  break;
               } 
            }
              if(flag)
              printf("YES\n");
              else
              printf("NO\n");  
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值