欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

POJ 2785 4 Values whose Sum is 0(hash)

程序员文章站 2022-06-17 19:48:22
...

题目链接:POJ 2785 4 Values whose Sum is 0

POJ 2785 4 Values whose Sum is 0(hash)
POJ 2785 4 Values whose Sum is 0(hash)

  • 如果题目中出现的每个数都不会超过105,因此直接作为数组下标是可行的,但是如果输入可能是109大小的整数甚至更大,比如10000000000,就不能将它们直接作为数组下标了。

  • 看到大佬的博客学到了一招:

 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 x = hash[10000000000] ; 即可 很方便,也就是说 这个 hash 直接实现了对 特别大的数的标记。
#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
typedef long long ll;

using namespace std;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const int maxn = 4005;

struct hash_map
{
	static const int mask = 0x7fffff;
	int p[8388608],q[8388608];
	
	void clear()	//初始化为0 
	{
		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;

int main()
{
	int n;
	scanf("%d",&n);
	
	vector<int> v1,v2,v3,v4;
	int cnt = 0;
	
	while(n--)
	{
		int tmp;
		cin>>tmp;
		v1.push_back(tmp);
		cin>>tmp;
		v2.push_back(tmp);
		cin>>tmp;
		v3.push_back(tmp);
		cin>>tmp;
		v4.push_back(tmp);
	}
	
	int len1 = v1.size() ;
	int len2 = v2.size() ;
	int len3 = v3.size() ;
	int len4 = v4.size() ;
	
	hash.clear();
	
	for(int i=0;i<len1;i++)
		for(int j=0;j<len2;j++)
			hash[ v1[i]+v2[j] ]++;
	
	for(int i=0;i<len3;i++)
		for(int j=0;j<len4;j++)
			cnt += hash[ -v3[i]-v4[j] ];
	
	printf("%d\n",cnt);
	return 0;
}