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 }

 

posted @ 2020-09-29 23:19  反射狐  阅读(106)  评论(0)    收藏  举报