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): 23782    Accepted Submission(s): 6024


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>
#include<string.h>
#include<math.h>
#include<algorithm>
#define MYDD 1130

using namespace std;
typedef double DO;

int main() {
	int L,N,M,S;
	int a[MYDD/2],b[MYDD/2],c[MYDD/2],ans[501*501],X;
	int v=1;//测试数据看懂也不容易 
	while(scanf("%d%d%d",&L,&N,&M)!=EOF) {
		for(int j=1; j<=L; j++)
			scanf("%d",&a[j]);
		for(int j=1; j<=N; j++)
			scanf("%d",&b[j]);
		for(int j=1; j<=M; j++)
			scanf("%d",&c[j]);

		int sum_ab=1;//计算 a[] b[] 数组和的所有情况
		for(int j=1; j<=L; j++)
			for(int i=1; i<=N; i++) {
				ans[sum_ab]=a[j]+b[i];
				sum_ab++;
			}

		sort(ans+1,ans+sum_ab);

		scanf("%d",&S); 
		printf("Case %d:\n",v);
		for(int j=0; j<S; j++) {
			scanf("%d",&X);//需要查找的和
			int flag=0;//标记是否查找到 
			for(int j=1; j<=M; j++) {
				int turn=1,right=sum_ab;
				while(turn<=right) {
					int middle=(turn+right)/2;
					if(ans[middle]+c[j]==X) {
						flag=1;
						break;
					} else if(ans[middle]+c[j]<X)
						turn=middle+1;//区间右移 
					else
						right=middle-1;//区间左移 

					if(flag)
						break;
				}
			}

			if(flag)
				puts("YES");
			else
				puts("NO");

		}
		v++;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值