POJ3349-Snowflake Snow Snowflakes 哈希
原题:http://poj.org/problem?id=3349
大致题意:
给定n个长度为6的数组,求问是否存在两个数组a和b顺序相等或者逆序相等。(这里的相等是指循环相等,不用下标一一对应,比如1 2 3 4 5 6 和2 3 4 5 6 1是相等的)
思路:
对数组的每个元素求和并取大素数模,然后存入哈希表。
用链表存不要用vector。vector太慢了。
对哈希值相同的数组需要进一部暴力判断是否可以相等(避免冲突)
为了方便判断是否从不同下标开始是否相等(比如123456和234561)可以开长度为14的数组,把123456存为123456123456遍历查询。
1 #include "iostream" 2 #include "stdio.h" 3 #include "stdlib.h" 4 using namespace std; 5 typedef long long ll; 6 const ll mod=99991; 7 ll N; 8 typedef struct NODE { 9 ll v[14]; 10 NODE(){next=NULL;} 11 NODE *next; 12 }NODE; 13 NODE nos[mod]; 14 bool same(ll *a, ll *b){//顺序 15 for(ll i=1;i<=6;i++){ 16 if(a[i]!=b[i]) return false; 17 } 18 return true; 19 } 20 bool sameReverse(ll *a, ll *b){//逆序 21 for(ll i=1;i<=6;i++){ 22 if(a[i]!=b[7-i]) return false; 23 } 24 return true; 25 } 26 bool findEqual(ll id, ll *base){//遍历所有哈希值相同的NODE 27 NODE* curr=nos[id].next; 28 while(curr!=NULL){ 29 for(ll more=0;more<=5;more++){ 30 if(same(base, (curr->v)+more)) 31 return true; 32 if(sameReverse(base, (curr->v)+more)) 33 return true; 34 } 35 curr=curr->next; 36 } 37 return false; 38 } 39 int main() { 40 scanf("%lld", &N); 41 bool res=false; 42 for(ll i=1;i<=N;i++){ 43 ll sum=0; 44 NODE *node=(NODE *)malloc(sizeof(NODE)); 45 for(ll j=1;j<=6;j++){ 46 scanf("%lld", &(node->v[j])); 47 node->v[j+6]=node->v[j]; 48 sum+=node->v[j]; 49 } 50 if(sum>mod)sum%=mod; 51 52 if(res) continue; 53 54 res=findEqual(sum, node->v); 55 NODE* t=nos[sum].next; 56 nos[sum].next=node; 57 node->next=t; 58 } 59 printf("%s\n", res?"Twin snowflakes found.":"No two snowflakes are alike."); 60 61 return 0; 62 }