E - Can you find it?

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. 
InputThere 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. 
OutputFor 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

思路:正常遍历肯定爆了,涉及到四层循环。暴力时间严重超时。
可以采用空间换时间的做法,先两层循环计算L,N的数据保存成新数组,再用二分法进行遍历。

#include<cstdio>
#include<iostream>
#include <string>
#include<algorithm>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;

 
int main(void) {
	int L,N,M,S;
	int LL[501],NN[501],MM[501];
	long long LLNN[501*501];
	int SS[1001];
	int begin,end,mid;
	long long sum;
	bool check =false;
	int ex = 1;
	//freopen("main.txt", "r",stdin);
	 while(~scanf("%d%d%d", &L, &N, &M)) {
	 		printf("Case %d:\n", ex++);
	 	for(int i = 0; i < L; i++) {
	 		scanf("%d", &LL[i]);
		 }
		for(int i = 0; i < N; i++) {
	 		scanf("%d", &NN[i]);
		 }
	 	for(int i = 0; i < M; i++) {
	 		scanf("%d", &MM[i]);
		 }
		 sort(MM, MM+M);
		 int p = 0;
		 for(int i = 0; i < L; i++) {
		 	for(int j = 0; j < N; j++ ) {
		 		LLNN[p++] = LL[i] + NN[j];
			 }
		 }
		 sort(LLNN, LLNN + p);
//		for(int i = 0; i < p; i++) {
//			printf("%d ", LLNN[i]);
//		
//		}
//		printf("\n");
		 scanf("%d", &S);
		 for(int i = 0; i < S; i++) {
		 	scanf("%d", &SS[i]);
		 }
		
		for(int ii = 0; ii < S; ii++) {
		 	check = false;
			for(int i = 0; i < M; i++) {
		 	 		begin = 0; 
		 	 		end = p - 1;
		 	 		while(begin <= end) {
		 	 			mid = (begin + end) / 2;
		 	 		//	printf("mid%d\n", mid);
					//	  printf("LLNN %d MM[i] %d sum %d\n",LLNN[mid], MM[i], LLNN[mid] + MM[i]);	
						if(LLNN[mid] + MM[i] == SS[ii]) {	
		 	 				check = true;
		 	 				break;
						}else if(LLNN[mid] + MM[i] > SS[ii]) {
							end = mid - 1;
						}else {
							begin = mid + 1;
						}
		 			}
				if(check) {
					break;
				}	
		 	}
		 	if(check) {
		 		printf("YES\n");
			 }else {
			 	printf("NO\n");
			 }
		}
	 
	} 
	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值