UVa1152 和为0的4个值

本文深入探讨了哈希技术的原理与应用,通过对比map和hash的特点,讲解了如何利用哈希解决特定问题,提供了详细的代码实现,帮助读者理解和掌握哈希技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要是学会哈希技术,要自己能理解掌握,哈希技术一定要熟悉,
参考了一些大佬的代码:
https://blog.youkuaiyun.com/lth404391139/article/details/44118353

这里因为是用hash存的A。B数组的和,然后与C,D数组的和,双向相遇法考虑,有人可能回想用A,C与B,D会怎样呢,其实都是一样的,仔细想想。
体会map和hash 的区别
map: map会比哈希更慢一点,
有时候注意开大一点的hash,空间换时间


#include<cstdio>
#include<cstring>
#include<map>
 
using namespace std;
 
 
map<int,int>MAP;
int a[5][5000];
 
int main()
{
    int n,i,j,tt,ans;
 
 
    while(~scanf("%d",&n))
    {
        ans=0;
        MAP.clear();
        for(j=1;j<=n;j++)
            for(i=1;i<=4;i++)
                scanf("%d",&a[i][j]);
 
 
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {
                tt=a[1][i]+a[2][j];
                MAP[tt]++;
            }
 
         for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {
                tt=a[3][i]+a[4][j];
                ans+=MAP[-tt];
            }
 
            printf("%d\n",ans);
 
    }
 
    return 0;
}

hash:

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
 
//const int mod=3999971;
const int mod=10000007;
 
int head[mod+50];
int next[16000000+50];
 
int a[5][5000];
int res[16000000+50];
void insert_hash(int x)
{
 
    int v=abs(res[x]%mod);
    next[x]=head[v];
    head[v]=x;
}
 
int find_hash(int x)
{
    int cnt=0;
    int t=abs(x);
    int u=head[t%mod];
    while(u!=-1)
    {
        if(res[u]==x)
            cnt++;
        u=next[u];
    }
    return cnt;
}
int main()
{
    int n,i,j,tt,ans,k;
 
 
    while(~scanf("%d",&n))
    {
        ans=0;
        memset(head,-1,sizeof head);
        for(j=1;j<=n;j++)
            for(i=1;i<=4;i++)
                scanf("%d",&a[i][j]);
 
        k=0;
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {
                tt=a[1][i]+a[2][j];
                res[++k]=tt;
                insert_hash(k);
            }
 
 
         for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {
                tt=a[3][i]+a[4][j];
                ans+=find_hash(-tt);
            }
 
            printf("%d\n",ans);
 
    }
 
    return 0;
}

hash2:

#include<bits/stdc++.h>
#define hashsize 1000000
using namespace std;
 
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        vector<int>Hash[hashsize];
        int n;
        scanf("%d",&n);
        vector<int>vec[4];
        while(n--)
        {
            int temp;
            for(int i=0;i<4;i++)
            {
                scanf("%d",&temp);
                vec[i].push_back(temp);
            }
        }
        for(unsigned int i=0;i<vec[0].size();i++)
            for(unsigned int j=0;j<vec[1].size();j++)
            {
                int s=vec[0][i]+vec[1][j];
                int h=abs(s)%hashsize;
                Hash[h].push_back(s);
            }
        int ans=0;
        for(unsigned int i=0;i<vec[2].size();i++)
            for(unsigned int j=0;j<vec[3].size();j++)
            {
                int s=-vec[2][i]-vec[3][j];
                int h=abs(s)%hashsize;
                int cnt=0;
                for(unsigned int k=0;k<Hash[h].size();k++)
                    if(Hash[h][k]==s)
                        cnt++;
                ans+=cnt;
            }
        printf("%d\n",ans);
        if(t) puts("");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值