• Uva 1152 和为0的4个值 hash/二分


    题意:
    给定4个n(1 <= n <= 4000)元素集合A, B, C, D,要求分别从中选取一个元素a, b, c, d,使得a+b+c+d = 0,问有多少种选法。
    分析:
    显然四重循环是过不了的,我先想到的是用map把a+b,c+d分别保存起来,然后在查找统计。超时。。。。
    然后书上说用哈希表去实现,看到有的题解hash表示的太巧妙了,学习一下。
    还有就是这题可以用二分解决,先计算出a+b,然后枚举c+d,然后二分找出范围即可。

    hash 630ms:

    #include<cstdio>
    #include<cstring>
    const int N=4005;
    int a[4][N];
    struct Hash_map
    {
        static const int mask=0x7fffff;
        int p[mask+1],q[mask+1];
        void clear()
        {
            memset(q,0,sizeof(q));
        }
        int& operator [](int k)
        {
            int i;
            for(i=k&mask;q[i]&&p[i]!=k;i=(i+1)&mask);
            p[i]=k;
            return q[i];
        }
    };
    Hash_map Hash;
    int main()
    {
        int T;scanf("%d",&T);
        for(int t=0;t<T;t++){
            int n;
            scanf("%d",&n);
            for(int j=0;j<n;j++)
                for(int i=0;i<4;i++)scanf("%d",&a[i][j]);
            Hash.clear();
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                Hash[a[0][i]+a[1][j]]++;
            int ans=0;
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                ans+=Hash[-a[2][i]-a[3][j]];
            if(t)printf("
    ");
            printf("%d
    ",ans);
        }
        return 0;
    }

    二分 、2720ms:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=4005;
    int a[4][N];
    int sum[N*N];
    int main()
    {
        int T;scanf("%d",&T);
        for(int t=0;t<T;t++){
            int n;
            scanf("%d",&n);
            for(int j=0;j<n;j++)
                for(int i=0;i<4;i++)scanf("%d",&a[i][j]);
            int cnt=0;
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                sum[cnt++]=a[0][i]+a[1][j];
            int ans=0;
            sort(sum,sum+cnt);
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                ans+=upper_bound(sum,sum+cnt,-a[2][i]-a[3][j])-lower_bound(sum,sum+cnt,-a[2][i]-a[3][j]);
            if(t)printf("
    ");
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    idea编辑器快捷键
    双随机系统遇到的简单样式问题
    HTTP笔记八
    HTTP笔记七
    HTTP笔记六
    HTTP笔记五
    HTTP笔记四
    HTTP笔记三
    HTTP笔记二
    HTTP笔记一
  • 原文地址:https://www.cnblogs.com/01world/p/5651214.html
Copyright © 2020-2023  润新知