• HDU 4334 Contest 4


    本来以为是一道水题,好吧,做了才知道,出题的人有多牛。二分搜索是不可能的了,因为会超内存。。。

    看到别人的搜索两个集合的提示,我就自己一边去想了。终于想出来了:

    可以这样做,先把每两个集合的和值枚举出来并成一个大集合,排序,去重。剩下一个集合,于是,共三个集合。

    枚举小的那个集合的元素,搜索两个大的集合。可以这样做,定义一个初始为指向最小元素的指针,一个指向最大元素的指针(两个指针是指向不同的集合的),两者之和相等则返回,小于则移动小指针+1,否则移动大指针-1.直至二者相等退出。然后再用两个指针交换指向另一个集合,重复上述过程。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL __int64
    using namespace std;
    
    LL A[41000],B[41000];
    LL C[41000];
    int pa,pb;
    LL S[5][250];
    
    bool find_t(LL a){
    	int tma,tmi;
    	LL tmp;
    	tma=pa,tmi=1;
    	while(tma>=1&&tmi<=tma&&tmi<=pb){
    		tmp=A[tma]+B[tmi];
    		if(tmp==a) return true;
    		else if(tmp<a) tmi++;
    		else tma--;
    	}
    	tma=pb,tmi=1;
    	while(tma>=1&&tmi<=tma&&tmi<=pa){
    		tmp=A[tmi]+B[tma];
    		if(tmp==a) return true;
    		else if(tmp<a) tmi++;
    		else tma--;
    	}
    	return false;
    }
    
    bool cmp(LL a,LL b){
    	if(a<b) return true;
    	return false;
    }
    
    int main(){
    	int T,n;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d",&n);
    		for(int i=0;i<5;i++){
    			for(int j=1;j<=n;j++)
    			scanf("%I64d",&S[i][j]);
    		}
    		pa=pb=0;
    		C[0]=A[0]=B[0]=0;
    		
    		int tb=0;
    		for(int i=0;i<=1;i++){
    			pb=0;
    			for(int j=1;j<=n;j++){
    				if(tb==0)
    				C[++pb]=C[0]+S[i][j];
    				else{
    					for(int k=1;k<=tb;k++)
    					B[++pb]=C[k]+S[i][j];
    				}
    			}
    			if(tb==0)
    			tb=n;
    			else tb=tb*n;
    		}
    
    		tb=0;
    		for(int i=2;i<4;i++){
    			pa=0;
    			for(int j=1;j<=n;j++){
    				if(tb==0)
    				C[++pa]=C[0]+S[i][j];
    				else{
    					for(int k=1;k<=tb;k++)
    					A[++pa]=C[k]+S[i][j];
    				}
    			}
    			if(tb==0)
    			tb=n;
    			else tb=tb*n;
    		}
    		
    		int t=1;
    		sort(A+1,A+pa+1,cmp);
    		for(int i=2;i<=pa;i++)
    		if(A[i]!=A[t]){
    			A[++t]=A[i];
    		}
    		pa=t;
    		
    		t=1;
    		sort(B+1,B+pb+1,cmp);
    		for(int i=2;i<=pb;i++)
    		if(B[i]!=B[t]){
    			B[++t]=B[i];
    		}
    		pb=t;
    		
    		bool flag=false;
    
    		for(int j=1;j<n;j++){
    			if(find_t(-S[4][j])){
    				flag=true;
    				break;
    			}
    		}
    			
    		if(flag)
    		printf("Yes
    ");
    		else printf("No
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    [恢]hdu 2502
    [恢]hdu 1008
    [恢]hdu 2073
    [恢]hdu 2500
    [恢]hdu 2501
    [恢]hdu 2190
    [恢]hdu 2535
    [恢]hdu 2085
    [恢]hdu 2067
    [恢]hdu 2504
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4115549.html
Copyright © 2020-2023  润新知