poj_3349 哈希
2015-01-24 13:36
309 查看
题意:n片雪花,判断是否存在两个“相同的”雪花。
每个雪花由6个整数组成,两个雪花相同是说从一个雪花的任意一个数开始遍历可以得到另一个雪花的6个整数,无论是顺时针或者是逆时针方向,比如:123456有如下12种组合
123456 | 654321
234561 | 543216
345612 | 432165
456123 | 321654
561234 | 216543
612345 | 165432
这里认为其中任意两组数都是“相同的”。
思路:使用哈希,读入一个雪花时,将该雪花的12种可能性全部存入哈希表中,若后面的输入与前面的冲突,认为存在重复的雪花。
尽可能的避免若干个不同的雪花的哈希值相同,所以使用HASH_BASE为12*100000以上的最小素数,如果两个雪花哈希值相同,则依次比较该值下的所有雪花们,因为极有可能存在相同的情况。
code:
注意使用int num[2][12]技巧来模拟一个雪花的12种情况。
每个雪花由6个整数组成,两个雪花相同是说从一个雪花的任意一个数开始遍历可以得到另一个雪花的6个整数,无论是顺时针或者是逆时针方向,比如:123456有如下12种组合
123456 | 654321
234561 | 543216
345612 | 432165
456123 | 321654
561234 | 216543
612345 | 165432
这里认为其中任意两组数都是“相同的”。
思路:使用哈希,读入一个雪花时,将该雪花的12种可能性全部存入哈希表中,若后面的输入与前面的冲突,认为存在重复的雪花。
尽可能的避免若干个不同的雪花的哈希值相同,所以使用HASH_BASE为12*100000以上的最小素数,如果两个雪花哈希值相同,则依次比较该值下的所有雪花们,因为极有可能存在相同的情况。
code:
#include <iostream> #include <fstream> #include <cstdio> #include <algorithm> using namespace std; const int HASH_BASE = 1200007;//100000*12以上的最小素数 const int NODE_NUMBER = 1200010;//node个数 int hashTable[HASH_BASE]; int cur; struct HashNode{ int num[6]; int next; }; HashNode node[NODE_NUMBER]; void initHashTable() { cur = 0; for (int i = 0; i < HASH_BASE; i++) { hashTable[i] = -1; } } unsigned getHash(int num[]) { unsigned int value = 0; for (int i = 0; i < 6; i++) { value += num[i]; } return value%HASH_BASE; } void insertHashNode(int num[], unsigned value) { for (int i = 0; i < 6; i++) { node[cur].num[i] = num[i]; } node[cur].next = hashTable[value]; hashTable[value] = cur; cur++; } bool compare(int num1[], int num2[]) { for (int i = 0; i < 6; i++) { if (num1[i] != num2[i]) return false; } return true; } bool searchHash(int num[]) { unsigned value = getHash(num); int next = hashTable[value]; while (next != -1) { if (compare(num, node[next].num)) return true; next = node[next].next; } insertHashNode(num, value); return false; } int main() { fstream in("input.txt"); int num[2][12];//各种情况,num[0]->clockwise,num[1]->counterclockwise int i, j; int n; bool find = false; initHashTable(); scanf("%d", &n); for (i = 0; i < n; i++) { //设置12种可能情况 for (j = 0; j < 6; j++) { scanf("%d", &num[0][j]); num[0][6 + j] = num[0][j]; } for (j = 0; j < 6; j++) { num[1][j] = num[1][6 + j] = num[0][5 - j]; } if (find) continue; for (j = 0; j < 6; j++) { if (searchHash(num[0] + j) || searchHash(num[1] + j)) { find = true; break; } } } if (find) printf("Twin snowflakes found.\n"); else printf("No two snowflakes are alike.\n"); //system("pause"); return 0; }
注意使用int num[2][12]技巧来模拟一个雪花的12种情况。
相关文章推荐
- poj-3349-哈希
- poj 3349:Snowflake Snow Snowflakes(哈希查找,求和取余法+拉链法)
- POJ-3349 Snowflake Snow Snowflakes 哈希
- POJ 3349 Snowflake Snow Snowflakes(哈希hash)
- POJ 3349 重复的雪花(哈希)
- POJ3349--Snowflake Snow Snowflakes(哈希)
- 哈希—— POJ 3349 Snowflake Snow Snowflakes
- POJ 3349 (哈希)
- POJ 3349-Snowflake Snow Snowflakes(哈希)
- POJ训练计划3349_Snowflake Snow Snowflakes(哈希)
- POJ 3349 Snowflake Snow Snowflaks <数的哈希>
- poj 3349 哈希 简单拉链(卡时间过去的。。。)
- POJ 3349 - 数值哈希(这辈子只服数据量)
- POJ_3349_Snowflake_哈希
- POJ 3349 简单哈希
- POJ 3349 所谓哈希
- poj 3349 典型哈希
- poj-3349-Snowflake Snow Snowflakes-哈希
- ***POJ 3349 Snowflake Snow Snowflakes(哈希)
- poj_3349 Snowflake Snow Snowflakes(数字哈希)