HDU 2141 Can you find it?【二分查找】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37867156/article/details/81569875

问题描述:躺在床上不久我便心安理得的睡着了, 我梦见老板给我发了K个红包于是我便开开心心地去超市买吃的. 超市一共有ABC三个货架, 每个货架上都有若干种商品(每种有无限多个), 比如A货架上的第i种商品的价格是Ai元.

对于每个红包, 我想要从三个货架上各拿一个商品, 把红包里的钱恰好花光, 这可能吗?

Input

每个输入包含多组样例. 
每组样例的第一行有三个整数L, N, M(1<=L, N, M<=500), 表示A, B, C三个货架上分别有L, N, M种商品
接下来三行, 每行分别有L, N, M个数字, 代表A, B, C三个货架上每种商品的价格.
第五行有一个整数K表示有K个红包, 1<=K<=1000 
接下来K行每行有一个数代表一个红包内的钱数

所有整数均在32位整型的范围内

Output

对于第i组样例输出一行Case i:
接下来K行对于每个红包的期望输出一行 如果可以满足则输出 YES 否则输出 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[i]+N[j]+M[h]=k,刚开始想的是直接三重for循环、结果超时了。经过分析,我们可以将L[i]+N[j]看作是一项,将他存在s[]数组中,然后再二分查找是否存在M[i]使得等式成立。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int maxn=555;
int a,b,c,k;
int L[maxn],N[maxn],M[maxn];
int s[250007];
int Find(int l,int r,int x){
	int mid;
	while(l<=r){
		mid=l+r>>1;
		if(s[mid]>x) r=mid-1;
		else if(s[mid]<x) l=mid+1;
		else return 1;
	}
	return -1;
}
int main(){
	int cnt=0;
	while(~scanf("%d%d%d",&a,&b,&c)){
		cnt++;
		for(int i=0;i<a;i++)
			scanf("%d",&L[i]);
		for(int i=0;i<b;i++)
			scanf("%d",&N[i]);
		for(int i=0;i<c;i++)
			scanf("%d",&M[i]);	
		int t=0;
		for(int i=0;i<a;i++){
			for(int j=0;j<b;j++){
				s[t++]=L[i]+N[j];
			}
		}
		sort(s,s+t);
		scanf("%d",&k);
		printf("Case %d:\n",cnt);
		int x;
		while(k--){
			scanf("%d",&x);
			int flag=-1;
			for(int i=0;i<c;i++){
				flag=Find(0,t-1,x-M[i]);
				if(flag==1) break;
			}
			if(flag==-1) printf("NO\n");
			else printf("YES\n");
		}
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37867156/article/details/81569875