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;
}

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/10193408.html