hdu 2141 二分 ll

来源:互联网 发布:阿里巴巴的域名是什么 编辑:程序博客网 时间:2024/06/01 09:56

HDU 2141
题意规定所有输入数字是32位整形数,所以输入的数据都可以用int类型。
把三组数存到三个数组a,b,c(大小分别为l,n,m)中,然后前两个数组的数分别相加存到r数组(大小为l*n)中,注意,这个和可能会超出int表示的范围,所以r数组是long long类型的。

然后遍历第三个数组c,在r数组中二分查找s-c[i]。时间
复杂度是mlog(l*n)。
三层for循环,能做出来,但是肯定会超时了。时间复杂度l*n*m。
如果遍历r数组,在c数组中二分查找s-r[i]。时间复杂度为(l*n)logm。并不能显著降低时间复杂度,会超时。

#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>#define ll long longusing namespace std;int l,n,m,ns,s,in,i,j;int a[505],b[505],c[505];ll r[505*505];bool f(int k){    int left=0,right=in-1,mid;    while(left<=right){        mid=(left+right)/2;        if(r[mid]==k)            return true;        else if(r[mid]<k)            left=mid+1;        else            right=mid-1;    }    return false;}int main(){    int co=1;    while(~scanf("%d%d%d",&l,&n,&m)){        for(i=0;i<l;i++)            scanf("%d",&a[i]);        for(i=0;i<n;i++)            scanf("%d",&b[i]);        for(i=0;i<m;i++)            scanf("%d",&c[i]);        sort(c,c+m);        in=0;        for(i=0;i<l;i++)            for(j=0;j<n;j++)                r[in++]=a[i]+b[j];        sort(r,r+in);        in=unique(r,r+in)-r;        scanf("%d",&ns);        cout<<"Case "<<co++<<":"<<endl;        while(ns--){            scanf("%d",&s);            if(s>r[in-1]+c[m-1]||s<r[0]+c[0]){                printf("NO\n");                continue;            }            for(i=0;i<m;i++)                 if(f(s-c[i])){                 //if(binary_search(r,r+in,s-c[i])){                    printf("YES\n");                    break;                }            if(i>=m)                printf("NO\n");        }    }    return 0;}
原创粉丝点击