UVA 1152 4 Values whose Sum is 0

来源:互联网 发布:注册中文域名多少钱 编辑:程序博客网 时间:2024/06/15 03:45

哈希表:对于一个无法用数组来标记的数可以用hash 。例如 100这个数,我们要在后面判断它是否出现过,可以用数组vis标记vis[100]=1,但是如果要判断10000000000是否出现过,就不能用普通的数组进行标记了,因为普通数组最大也就开到10^8左右,那么就要用hash来标记了

hash模板:

struct Hash_map{    static const int mask=0x7fffff;    int p[8388608],q[8388608];    void clear()    {        for(int i=0; i<=mask; ++i)            q[i]=0;    }    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;
这个hash结构体实现了对[]的重载,现在就可以用hash[10000000000]++来标记了,查询的时候就用int cnt=hash[10000000000]就可以了。这个hash实现了对特别大的数进行标记


题意:给定4个n个元素集合A,B,C,D,要求分别从中选取一个元素a,b,c,d,使得a+b+c+d=0,问有几种选法

解题思路:直接四重循环枚举肯定超时,可以先将a+b存到hash表里,然后再用二重循环枚举c和d,查一查-(c+d)有多少种等于a+b的方法

代码:

#include <iostream>#include <algorithm>#include <string>#include <cstring>#include <cstdio>#include <cmath>using namespace std;typedef long long ll;struct Hash{    static const int mask=0x7fffff;    int p[8388608],q[8388608];    void clear_()    {        for(int i=0; i<=mask; i++)        {            q[i]=0;        }    }    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];    }};int arr[4][4010];Hash hash_;int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n;        scanf("%d",&n);        hash_.clear_();        for(int i=0; i<n; i++)        {            scanf("%d%d%d%d",&arr[0][i],&arr[1][i],&arr[2][i],&arr[3][i]);        }        for(int i=0; i<n; i++)        {            for(int j=0; j<n; j++)            {                hash_[arr[0][i]+arr[1][j]]++;            }        }        int ans=0;        for(int i=0; i<n; i++)        {            for(int j=0; j<n; j++)            {                ans+=hash_[-(arr[2][i]+arr[3][j])];            }        }        printf("%d\n",ans);        if(t)printf("\n");    }    return 0;}




原创粉丝点击