哈希函数的设计

今天闲来没事在poj上刷提,找找当年读本科的感觉。

随便选了个有关哈希的poj3349,题目比较简单,就是要找左循环或者右循环之后相等的序列。显然要先用hash进行预处理,刚开始用的是简单的6个长度之和进行哈希,后来这样做超时。后来加了个限制条件,即六个数之间的绝对和之差的和也要相等,这样就进一步减少了冲突。从这个小例子可以看出,哈希函数的设计对于提高效率还是有很大作用的。

PS:用cin进行数据的输入超时,scanf通过。

代码见下:

// snowflakes.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "iostream"
#include "vector"
using namespace std;
#define PRIME 220000

typedef struct node
{
	long a[6];
}NODE;

vector<node> v[PRIME];

int judge(NODE tmp,int key)
{
	int i;
	vector<node>::iterator iter;
	for(iter=v[key].begin();iter!=v[key].end();iter++)
	{
		if( tmp.a[0]==iter->a[0] && tmp.a[1]==iter->a[1] && tmp.a[2]==iter->a[2] &&
			tmp.a[3]==iter->a[3] && tmp.a[4]==iter->a[4] && tmp.a[5]==iter->a[5] )
			return 1;
		else if( tmp.a[0]==iter->a[1] && tmp.a[1]==iter->a[2] && tmp.a[2]==iter->a[3] &&
			tmp.a[3]==iter->a[4] && tmp.a[4]==iter->a[5] && tmp.a[5]==iter->a[0] )
			return 1;
		else if( tmp.a[0]==iter->a[2] && tmp.a[1]==iter->a[3] && tmp.a[2]==iter->a[4] &&
			tmp.a[3]==iter->a[5] && tmp.a[4]==iter->a[0] && tmp.a[5]==iter->a[1] )
			return 1;
		else if( tmp.a[0]==iter->a[3] && tmp.a[1]==iter->a[4] && tmp.a[2]==iter->a[5] &&
			tmp.a[3]==iter->a[0] && tmp.a[4]==iter->a[1] && tmp.a[5]==iter->a[2] )
			return 1;
		else if( tmp.a[0]==iter->a[4] && tmp.a[1]==iter->a[5] && tmp.a[2]==iter->a[0] &&
			tmp.a[3]==iter->a[1] && tmp.a[4]==iter->a[2] && tmp.a[5]==iter->a[3] )
			return 1;
		else if( tmp.a[0]==iter->a[5] && tmp.a[1]==iter->a[0] && tmp.a[2]==iter->a[1] &&
			tmp.a[3]==iter->a[2] && tmp.a[4]==iter->a[3] && tmp.a[5]==iter->a[4] )
			return 1;

		i=tmp.a[0];tmp.a[0]=tmp.a[5];tmp.a[5]=i;
		i=tmp.a[1];tmp.a[1]=tmp.a[4];tmp.a[4]=i;
		i=tmp.a[2];tmp.a[2]=tmp.a[3];tmp.a[3]=i;

		if( tmp.a[0]==iter->a[0] && tmp.a[1]==iter->a[1] && tmp.a[2]==iter->a[2] &&
			tmp.a[3]==iter->a[3] && tmp.a[4]==iter->a[4] && tmp.a[5]==iter->a[5] )
			return 1;
		else if( tmp.a[0]==iter->a[1] && tmp.a[1]==iter->a[2] && tmp.a[2]==iter->a[3] &&
			tmp.a[3]==iter->a[4] && tmp.a[4]==iter->a[5] && tmp.a[5]==iter->a[0] )
			return 1;
		else if( tmp.a[0]==iter->a[2] && tmp.a[1]==iter->a[3] && tmp.a[2]==iter->a[4] &&
			tmp.a[3]==iter->a[5] && tmp.a[4]==iter->a[0] && tmp.a[5]==iter->a[1] )
			return 1;
		else if( tmp.a[0]==iter->a[3] && tmp.a[1]==iter->a[4] && tmp.a[2]==iter->a[5] &&
			tmp.a[3]==iter->a[0] && tmp.a[4]==iter->a[1] && tmp.a[5]==iter->a[2] )
			return 1;
		else if( tmp.a[0]==iter->a[4] && tmp.a[1]==iter->a[5] && tmp.a[2]==iter->a[0] &&
			tmp.a[3]==iter->a[1] && tmp.a[4]==iter->a[2] && tmp.a[5]==iter->a[3] )
			return 1;
		else if( tmp.a[0]==iter->a[5] && tmp.a[1]==iter->a[0] && tmp.a[2]==iter->a[1] &&
			tmp.a[3]==iter->a[2] && tmp.a[4]==iter->a[3] && tmp.a[5]==iter->a[4] )
			return 1;
	}
	return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
	long i,n,key,sum;
	int flag[PRIME]={0};
	node tmp;
	i=0;
	cin >> n;
	while(n--)
	{
		for(i=0,sum=0;i<6;i++)
		{
			//scanf("%ld",&tmp.a[i]);
			cin >> tmp.a[i];
			sum += tmp.a[i];
		}
		//hash
		sum += abs(tmp.a[0]-tmp.a[1]) + abs(tmp.a[1]-tmp.a[2]) + abs(tmp.a[2]-tmp.a[3]) + abs(tmp.a[3]-tmp.a[4]) + abs(tmp.a[4]-tmp.a[5]) + abs(tmp.a[5]-tmp.a[0]);
		key = sum%210011;
		if(flag[key]==1)
		{
			if(judge(tmp,key)==1)
			{
				cout << "Twin snowflakes found.\n";
				return 0;
			}
		}
		else if(flag[key]==0)
			flag[key]=1;
		v[key].push_back(tmp);
	}
	cout << "No two snowflakes are alike.\n";
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值