POJ3349: Snowflake Snow Snowflakes(hash 表)

考察hash表:

每一个雪花都有各自的6个arm值,如果两个雪花从相同或者不同位置开始顺时针数或者逆时针数可以匹配上,那么这两个雪花就是相等的。

我们采用hash的方法,这样每次查询用时为O(1),总用时为O(n)。

hash的本质是把值映射到地址或者下标,如果不同的key值对应到相同的indice上的话,就需要进行chaining处理,吧indice指向一个链表,链表的每一个节点存储共享同一indice的不同key值。

因此问题的核心变成:吧相等的雪花映射到相同的indice上。这里雪花是一个特殊类型,我们不能直接映射,所以我们把每一片雪花的6个arm值的和取模作为该雪花的key值。

即:key=(arm[0]+arm[1]+arm[2]+arm[3]+arm[4]+arm[5]);

AND indice=key%prime

因为题目开出的雪花个数范围最大是10^6。所以我们取一个离10^6很近的99983作为prime(PS:事实上,在10^6周围的大质数都可以,可以随便挑一个)。

但这里又有一个问题:即使key值相同也不能代表两个雪花相同,所以我们当我们把所有的雪花映射到hash表上时,每一个indice指向的邻接表里存储的雪花仅仅是arm和相同。

-----------------------------------------------------------------------------------------

好了,现在我们开始查找相同雪花了:

顺序地,每一个雪花进行枚举,计算他的indice值,然后查看indice指向的邻接表是否为空,若为空,则说明还没有“相同”的雪花的记录。若不为空,则说明有arm和与当前雪花arm和相同的雪花在hash表中,所以我们进一步在indice指向的邻接表中逐一查找。如果发现有arm顺序“匹配”的雪花,就输出“Twin snowflakes found.”,然后程序结束。如果邻接表中没有我们想要的“相等”的雪花,那么我们就枚举下一个雪花。

如果枚举玩所有雪花都没有找到与之相等的雪花,则输出“No two snowflakes are alike.”,程序结束。

 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
const int max_size=100010;
const int prime=99991;
vector<int> hsh[prime];
int arm[max_size][6];
int n;
bool isTheSame(int a,int b){
	for(int i=0;i<6;i++){
		if((//clockwise
			arm[a][0]==arm[b][i]&& arm[a][1]==arm[b][(i+1)%6]&&
			arm[a][2]==arm[b][(i+2)%6]&& arm[a][3]==arm[b][(i+3)%6]&&
			arm[a][4]==arm[b][(i+4)%6]&& arm[a][5]==arm[b][(i+5)%6])
		||
		//counter clockwise
		(	arm[a][0]==arm[b][i]&& arm[a][1]==arm[b][(i+5)%6]&&
			arm[a][2]==arm[b][(i+4)%6]&& arm[a][3]==arm[b][(i+3)%6]&&
			arm[a][4]==arm[b][(i+2)%6]&& arm[a][5]==arm[b][(i+1)%6]))
		return true;
	}
	return false;
}
int main(){
	scanf("%d",&n); long long sum,key;
	for(int i=0;i<n;i++){
		for(int j=0;j<6;j++){
			scanf("%d",&arm[i][j]);
		}
	}
	for(int i=0;i<n;i++){
		sum=0;
		for(int j=0;j<6;j++){
			sum+=arm[i][j]*2;
		}
		key=sum%prime;
		vector<int>::size_type k;
		for(k=0;k<hsh[key].size();k++){
			if(isTheSame(i,hsh[key][k])){
				printf("Twin snowflakes found.\n");
				exit(0);
			} 

		}
		hsh[key].push_back(i);
	}
	printf("No two snowflakes are alike.\n");
}
时间: 2024-10-22 23:12:19

POJ3349: Snowflake Snow Snowflakes(hash 表)的相关文章

[poj3349]Snowflake Snow Snowflakes(hash)

Snowflake Snow Snowflakes Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 37615 Accepted: 9882 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your

POJ3349 Snowflake Snow Snowflakes (hash

Snowflake Snow Snowflakes Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 48624   Accepted: 12697 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true.

POJ3349 Snowflake Snow Snowflakes 【哈希表】

题目 很简单,给一堆6元组,可以从任意位置开始往任意方向读,问有没有两个相同的6元组 题解 hash表入门题 先把一个六元组的积 + 和取模作为hash值,然后查表即可 期望\(O(n)\) #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define LL long long int #define Redge(

POJ 3349 - Snowflake Snow Snowflakes - [hash]

题目链接:http://poj.org/problem?id=3349 Time Limit: 4000MS Memory Limit: 65536K Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your program will read information

Hash poj3349 Snowflake Snow Snowflakes

题意:判断是否有两片一样的雪花. Hash第一题,基本是抄的. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

POJ3349 Snowflake Snow Snowflakes

Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 39075   Accepted: 10232 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your program will read inf

POJ 3349 Snowflake Snow Snowflakes (哈希表)

题意:每片雪花有六瓣,给出n片雪花,六瓣花瓣的长度按顺时针或逆时针给出,判断其中有没有相同的雪花(六瓣花瓣的长度相同) 思路:如果直接遍历会超时,我试过.这里要用哈希表,哈希表的关键码key用六瓣花瓣的长度的和取余一个数得到,表中为雪花的存储位置address(即在snowflakes数组中的位置) 代码: #include<iostream> #include<vector> using namespace std; const int maxn=100000+100;//雪花最

POJ 3349 Snowflake Snow Snowflakes(哈希表)(转)

题意:判断有没有两朵相同的雪花.每朵雪花有六瓣,比较花瓣长度的方法看是否是一样的,如果对应的arms有相同的长度说明是一样的.给出n朵,只要有两朵是一样的就输出有Twin snowflakes found.,如果任何两个都是不一样的输出No two snowflakes are alike.n=100,000. 思路:最 简单的就是枚举每两片雪花,判断他们是否相同.时间复杂度为O(n*n),显然效果不理想.有没有更好的算法呢?hash:每读进一片雪花,将雪花 hash,判断hash表里是否有相同

POJ3349 Language: Snowflake Snow Snowflakes

POJ3349 Language: Snowflake Snow Snowflakes 题目:传送门 题解: 链表+hash的一道水题 填个坑补个漏... 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 typedef long long L