POJ-3349-Snowflake Snow Snowflakes - hash

http://poj.org/problem?id=3349

题意,给出6个数表示 一种六边形

 a1 a2 a3 a4 a5 a6

如果存在另一组 6个数 为 a数组平移得到,或者 翻转得到,那么 它代表的六边形与 a数组代表六边形是同一个


给出n组 这样的6元素数组,求其中是否有 2个 代表同一个六边形


对每给出的一组数据,可以对其6个数 用拉链法得到  一共 12个hash值,显然我们不可能把全部hash值都拿去判断。。必然TLE到死。。。

我们可以再哈希出一个 值, 这里窝直接  采用 12个中最小的 一个 作为 这个六边形的  最终hash值


然后求出所有的hash值比较有没相同的即可 

判断是否出现过 用到开放定址法的二次探测。。。




#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

typedef  unsigned long long  ull;
const ull mod= 149997    ;
const ull p=239;
ull min(ull a,ull b){return a<b?a:b;}
ull max(ull a,ull b){return a>b?a:b;}
ull pp[10];
ull val[14];
int tm[100000+5][10];
ull has[150000+5]; 
void pre(int x)
{
		int i,j;
	ull tmp=0;
	for (i=0;i<=5;i++)
	{
		int times=6;
		tmp=0;
		for (j=i;times--;j=(j+1)%6)
		{
			tmp=(tmp+tm[x][j]*pp[times]);
		}
		val[i]=tmp;
	}  
	for (i=0;i<=5;i++)
	{
		int times=6;
		tmp=0;
		for (j=i;times--; )
		{
			tmp=(tmp+tm[x][j]*pp[times]);
			j--;
			if (j<0) j=5;
		}
		val[6+i]=tmp;
	}
}  
int main()
{
	int n,i,j; 
	pp[0]=p; 
	for (i=1;i<=5;i++)
		pp[i]=pp[i-1]*p;
	cin>>n;
	for (i=1;i<=n;i++)
	{
		for (j=0;j<=5;j++)
		{
			scanf("%d",&tm[i][j]);
		}
	}
	
  	int flag=0; 
	for (i=1;i<=n;i++)
	{
		pre(i); 
		ull ret=val[0];
		for (j=0;j<12;j++) 
			ret=min(ret,val[j]); 
		
		int dd=ret%mod;
	    int tmp=dd,t=1; 
		while(has[tmp]!=0)
		{
			if (has[tmp]==ret) 
			{flag=1;break;}
			tmp=(dd+t*t)%mod;
			t++;
		}
			if (flag) 	break;
			else
				has[tmp]=ret;
	}  

	if (flag)
		printf("Twin snowflakes found.\n");
	else
		printf("No two snowflakes are alike.\n");

		return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值