POJ_3349_Snowflake_哈希

优化哈希了大半天,总想着避免冲突,结果冲突没解决,最后发现哈希的姿势是错的。。。

果然相对于学长讲的内容,还是老师更靠谱,在很多情况下想要避免哈希冲突很难,不如存储冲突元素再遍历。

这个题,即使我一开始的哈希是对的,由于哈希映射空间不是那么大,必须采用几个数字作为进制哈希才比较靠谱,那样也会增大时间开销,更何况这道题进制哈希很麻烦。


题意:

每个雪花有六个角,每个角一个长度,给你n个雪花的信息(顺时针或逆时针从任意一个角开始),判断是否存在两个雪花相同。



Input

The first line of input will contain a single integer n, 0 < n ≤ 100000, the number of snowflakes to follow. This will be followed by n lines, each describing a snowflake. Each snowflake will be described by a line containing six integers (each integer is at least 0 and less than 10000000), the lengths of the arms of the snow ake. The lengths of the arms will be given in order around the snowflake (either clockwise or counterclockwise), but they may begin with any of the six arms. For example, the same snowflake could be described as 1 2 3 4 5 6 or 4 3 2 1 6 5.

Output

If all of the snowflakes are distinct, your program should print the message:
No two snowflakes are alike.
If there is a pair of possibly identical snow akes, your program should print the message:
Twin snowflakes found.

由于难以进制哈希,直接把雪花所有角无顺序哈希成一个数,我最终AC的代码采用的是直接求和,然后对每个哈希值,开一个链表记录哈希空间下的雪花,每次哈希完,和相同哈希值下的所有雪花比较,注意比较时要从两个方向、任意角开始。


代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define mod 999983
#define mxn 100010
struct flake{
	int a[6];
	flake* nxt;
	flake(){nxt=NULL;}
}f[mxn];
struct hash_table{
	flake* first;
	hash_table(){first=NULL;}
}hash[mod];
int n;
int hashing(flake in){
	int ret=0;
	for(int i=0;i<6;++i)
		ret=(ret+in.a[i])%mod;
	return ret;
}
bool cmp(flake l,flake r){
	for(int i=0;i<6;++i){
		bool ok=true;
		for(int j=0;j<6;++j)	if(l.a[j]!=r.a[(j+i)%6]){
			ok=false;
			break;
		}
		if(ok)	return true;
	}
	for(int i=0;i<6;++i){
		bool ok=true;
		for(int j=0;j<6;++j)	if(l.a[j]!=r.a[(6-j+i)%6]){
			ok=false;
			break;
		}
		if(ok)	return true;
	}
	return false;
}
int main(){
	scanf("%d",&n);
	bool ans=false;
	for(int i=0;i<n;++i){
		for(int j=0;j<6;++j)
			scanf("%d",&f[i].a[j]);
		if(ans)	continue;
		int tem=hashing(f[i]);
		flake* cur=hash[tem].first;
		flake* pre=NULL;
		while(cur!=NULL){
			if(cmp(*cur,f[i])){
				ans=true;
				break;
			}
			pre=cur;
			cur=cur->nxt;
		}
		if(!ans){
			if(pre==NULL)
				hash[tem].first=f+i;
			else
				(pre->nxt)=f+i;
		}
	}
	if(ans)	puts("Twin snowflakes found.");
	else	puts("No two snowflakes are alike.");
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值