您的位置:首页 > 其它

HDU 4334 && ZOJ 3631

2012-08-02 20:30 337 查看
都是用到了求分别在两个数组中的两个数使之和满足某个条件

方法是先排序,然后用两个指针 i,j 分别指向两个数组的头和尾,再调整移动指针。

zoj 3631

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
    int i,j,a[50],ans,n,m;
    int sum1[40000],sum2[40000];
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    while(scanf("%d %d",&n,&m)==2){
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        memset(sum1,0,sizeof(sum1));
        memset(sum2,0,sizeof(sum2));
        for(i=0;i<=(1<<(n/2))-1;i++)
            for(j=1;j<=n/2;j++)
                if(i&(1<<(j-1)))
                    sum1[i]+=a[j];
        int p=n-n/2;
        for(i=0;i<=(1<<p)-1;i++)
            for(j=1;j<=p;j++)
                if(i&(1<<(j-1)))
                    sum2[i]+=a[j+n/2];
        sort(sum1,sum1+(1<<(n/2)));
        sort(sum2,sum2+(1<<p));
        ans=0;
        for(i=0,j=(1<<p)-1;i<(1<<(n/2))&&j>=0;)
            if(sum1[i]+sum2[j]<=m){
                ans=max(ans,sum1[i]+sum2[j]);
                i++;
            }
            else
                j--;
        printf("%d\n",ans);
    }
}


hdu 4334

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
__int64 a[10][201],sum2[50010],sum1[50010];

int main(){
    int t,T,i,j,n,k1,k2,flag,kk,p,q;
    __int64 tem;
    scanf("%d",&T);
    for(t=1;t<=T;t++){
        scanf("%d",&n);
        for(i=1;i<=5;i++){
            for(j=1;j<=n;j++)
                scanf("%I64d",&a[i][j]);
        }
        sort(a[5]+1,a[5]+1+n);

        kk=0;
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                sum1[kk++]=a[1][i]+a[2][j];
        sort(sum1,sum1+kk);
        k1=unique(sum1,sum1+kk)-sum1;

        kk=0;
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                sum2[kk++]=a[3][i]+a[4][j];
        sort(sum2,sum2+kk);
        k2=unique(sum2,sum2+kk)-sum2;

        flag=0;
        for(i=1;i<=n&& !flag;i++){
            for(p=0,q=k2-1;p<k1 && q>=0;){
                if(sum1[p]+sum2[q]+a[5][i]==0){
                    flag=1;
                    break;
                }
                else if(sum1[p]+sum2[q]+a[5][i]>=0)
                    q--;
                else
                    p++;
            }
        }
        if(flag==1)
            printf("Yes\n");
        else
            printf("No\n");
    }
}


hdu 4334 也可hash

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef __int64 int64;
#define inf 100007
int64 a[10][201],sum1[50010];//
int head[100010],cnt;
struct point{
    int64 real;//
    int next;
}edge[50010];
void add(int64 tem){  //
    int64 hash=tem%inf;   //                   先取余  !!!!!!!!
    if(hash<0)
        hash+=inf;
    
    for(int i=head[hash];i!=-1;i=edge[i].next){
        if(tem==edge[i].real)
            return;
    }
    edge[cnt].real=tem;
    edge[cnt].next=head[hash];
    head[hash]=cnt++;
}
int query(int64 tem){
    int64 hash=(-tem)%inf;
    if(hash<0)
        hash+=inf;
    for(int i=head[hash];i!=-1;i=edge[i].next){
        if((-tem)==edge[i].real){
            return 1;
        }
    }
    return 0;
}

int main(){
    int t,T,i,j,k,n,k1,flag,kk;
    scanf("%d",&T);
    for(t=1;t<=T;t++){
        memset(head,-1,sizeof(head));
        cnt=0;
        scanf("%d",&n);
        for(i=1;i<=5;i++){
            for(j=1;j<=n;j++)
                scanf("%I64d",&a[i][j]);//
        }

        kk=0;
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                add(a[1][i]+a[2][j]);

        flag=0;
        for(i=1;i<n && !flag;i++)
            for(j=1;j<=n && !flag;j++)
                for(k=1;k<=n && !flag;k++)
                    if(query(a[3][i]+a[4][j]+a[5][k])){
                        flag=1;
                        break;
                    }
        if(flag==1)
            printf("Yes\n");
        else
            printf("No\n");
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: