HDU 1241 Can you find it? (二分查找)

开始的思路是将A+B枚举,然后二分求X-A-B,这样超时了。

后来发现了一种更加巧妙的思路:先将A+B求和后排序,然后二分求X-c,此处将高效的二分用于求数量更大的A+B。果然换个角度,效率提高了N倍。

#include <stdio.h>
#include <algorithm>
#define maxn 500
using namespace std;
__int64 a[maxn],b[maxn],c[maxn],hun[maxn*maxn];
__int64 L,N,M,num;
bool bs(__int64 v)
{
	__int64 l,r,m;
	l=0;r=num;
	while(l<r)
	{
		m=(l+r)>>1;
		if(hun[m]==v)		return true;
		if(hun[m]<v)	l=m+1;
		else	r=m;
	}	
	return false;
}
bool search(__int64 x)
{
	__int64 i,j,k,t;
	for(i=0;i<M;i++)
	{
		t=x-c[i];
		if(t<hun[0] || t>hun[num-1])	continue;
		if(bs(t))
			return true;	
	}	
	return false;
}
int main()
{
	__int64 i,j,Q,X,ncase=1;
	while(scanf("%I64d%I64d%I64d",&L,&N,&M)==3)
	{
		for(i=0;i<L;i++)
			scanf("%I64d",&a[i]);
		for(i=0;i<N;i++)
			scanf("%I64d",&b[i]);
		for(i=0;i<M;i++)
			scanf("%I64d",&c[i]);
		num=0;
		for(i=0;i<L;i++)
		for(j=0;j<N;j++)
		{
			hun[num++]=a[i]+b[j];	
		}
		sort(hun,hun+num);
		sort(c,c+M);
		scanf("%I64d",&Q);
		printf("Case %I64d:\n",ncase++);
		while(Q--)
		{
			scanf("%I64d",&X);
			if(X>hun[num-1]+c[M-1] || X<hun[0]+c[0]){
				printf("NO\n");
				continue;
			}
			if(search(X))
				printf("YES\n");
			else printf("NO\n");
		}
	}
}


 

你可能感兴趣的:(c,search,ini)