POJ 2785 4 Values whose Sum is 0(hash)

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

POJ 2785 4 Values whose Sum is 0(hash)_第1张图片
POJ 2785 4 Values whose Sum is 0(hash)_第2张图片

  • 如果题目中出现的每个数都不会超过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
#include
#include
#include
#include
#include
#include
#include
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;
}

你可能感兴趣的:(暴力)