1. 程式人生 > >poj3349 散列表(hash)

poj3349 散列表(hash)

就是散列表的應用,把每片雜湊值相同的雪花排到一條鏈上去即可,每片雪花x的雜湊值 hash(x)=sum(x的六角)+mul(x的六角),會爆int

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100005
#define mod 99991
using namespace std;

struct Edge{
    int snow[6],next;
}edge[maxn];
int n,tot,head[maxn];

int H(int *a){ int sum=0,mul=1; for(int i=0;i<6;i++){ sum=(sum+a[i])%mod; mul=((long long)mul*a[i])%mod; } return (mul+sum)%mod; } bool equal(int *a,int *b){//比較兩片雪花是否相同 for(int i=0;i<6;i++) for(int j=0;j<6;j++){ bool eq=1; for(int
k=0;k<6;k++) if(a[(i+k)%6]!=b[(j+k)%6]) eq=0; if(eq) return 1; eq=1; for(int k=0;k<6;k++) if(a[(i+k)%6]!=b[(j-k+6)%6]) eq=0; if(eq) return 1; } return 0; } void addedge(int u,int *a){ ++tot;
for(int i=0;i<6;i++) edge[tot].snow[i]=a[i]; edge[tot].next=head[u]; head[u]=tot; } bool insert(int *a){ int val=H(a);//找到對應的那個雜湊 for(int i=head[val];i;i=edge[i].next)//先看雜湊裡面是否有相同的雪花 if(equal(edge[i].snow,a)) return 1; addedge(val,a); return 0; } int main(){ scanf("%d",&n); int a[10]; for(int i=1;i<=n;i++){ for(int j=0;j<6;j++) scanf("%d",&a[j]); if(insert(a)){ puts("Twin snowflakes found."); return 0; } } puts("No two snowflakes are alike."); return 0; }