1. 程式人生 > >POJ 3349 Snowflake Snow Snowflakes 哈希(鏈式解決沖突)

POJ 3349 Snowflake Snow Snowflakes 哈希(鏈式解決沖突)

printf int 存在 ash 循環 cstring ios include 哈希

題意:n個數列 每個數列6個元素a[i],a[i]<=1e7,兩個數列只要,經過若幹次循環移動能相等則定義為相似.
n<=1e5,問n個數列中 是否存在兩個數列相似?

每個數列只有6個數,則相似的最多12種,對每個數列算出其hash值 相同hash值插入同一個鏈表中.
查看新輸入的數列插入時是否產生沖突即可 O(n*12)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long
ll; typedef pair<int,int> ii; const ll mod=1200007; const ll inf=1e18; const int N=2e6+20; int head[N],ip; void init() { memset(head,-1,sizeof(head)); ip=0; } struct node{ int num[6]; int next; }e[N]; int get_hash(int *num)//hash?μ { int h=0; for(int i=0;i<6;i++) h+=num[i];
return h%mod; } void insert_hash(int *num,int h) { for(int i=0;i<6;i++) e[ip].num[i]=num[i]; e[ip].next=head[h]; head[h]=ip++; } bool compare(int *a,int *b) { for(int i=0;i<6;i++) { if(a[i]!=b[i]) return false; } return true; } bool search_hash(int
*num) { int h=get_hash(num); for(int i=head[h];i!=-1;i=e[i].next) { if(compare(num,e[i].num)) return true; } insert_hash(num,h); return false; } int main() { init(); int n,num[2][15]; bool flag=false; scanf("%d",&n); while(n--) { for(int i=0;i<6;i++) scanf("%d",&num[0][i]),num[0][i+6]=num[0][i];//clockwisze if(flag) continue; for(int i=0;i<6;i++) num[1][i]=num[1][i+6]=num[0][5-i]; for(int i=0;i<6;i++)//ê?·?ó?2úéú3?í? { if(search_hash(num[0]+i)||search_hash(num[1]+i)) { flag=true; break; } } } if(flag) printf("Twin snowflakes found.\n"); else printf("No two snowflakes are alike.\n"); return 0; }

POJ 3349 Snowflake Snow Snowflakes 哈希(鏈式解決沖突)