HDU 2141 详解

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

详细题解:
由该题题意可知,该题可用数组存储数据。贪心的解题方法便是将三组数据逐个遍历相加比较是否与输入的数据相等,如此一来便需要使用三个for语句,则时间复杂度为500*500*500,会超时,该方法不合理。。问题为A+B+C=X的问题,如果转换为A+B=X-C的问题,对A+B进行排序,寻找其中有无X-C这个数据若有则输出YES,否则输出NO;该方法需要用到排序和查找的思想,并且二分查找可以缩短查找时间,故而查找采用二分查找法,排序采用快排函数sort(),头文件为#include <algorithm>。。
分别用数组存放三个序列A,B,C,并用另外一个数组存放序列A与序列B 的和的所有可能;随后对新存放的和数组进行排序,然后从序列C的起始数据开始查找是否有和数组中的某一数据与X-C相等,若相等,则返回真,若不相等则返回假。

下面附上AC代码:

#include<stdio.h>
#include <algorithm>
#include<iostream>
using namespace std;
int l,n,m,s,x;
int ll[505],nn[505],mm[505],ss[250005];
int find(int a,int b,int c){
	if(b>c)
		return 0;
	int mid=(b+c)/2;
	if(ss[mid]==a)
		return 1;
	else{
		if(ss[mid]<a)
			find(a,mid+1,c);
		else
			find(a,b,mid-1);
	}
}
int main(){
	int i,j,k;
	int cas=1;
	while(cin>>l>>n>>m){
		for(i=0;i<l;i++)
			cin>>ll[i];
		for(j=0;j<n;j++)
			cin>>nn[j];
		for(k=0;k<m;k++)
			cin>>mm[k];
		for(k=0,i=0;i<l;i++)
			for(j=0;j<n;j++)
				ss[k++]=ll[i]+nn[j];
		sort(ss,ss+k);
		cin>>s;
		cout<<"Case "<<cas++<<":"<<endl;
		for(i=0;i<s;i++){
			cin>>x;
			for(j=0;j<m;j++)
				if(find(x-mm[j],0,k-1))
					break;
			if(j==m)
				cout<<"NO"<<endl;
			else
				cout<<"YES"<<endl;
		}
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值