POJ3349 哈希表

哈希表模板题,因为相同雪花的长度相同,顺序不一样,那么相同雪花的累加和累乘相等。利用这个性质可以用哈希表将雪花分类。之后再分类查找。

这样设计哈希函数:(长度累加+长度累乘)%P,这个P是接近N的一个质数,这样可以使得哈希表尽量分散。

然后就是查找,判断是否是同一片雪花。

这道题居然卡了stl,用list交T了好几次,手写链表才能过,POJ真的很严格。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <list>
using namespace std;
typedef long long LL;
int n,s[100010][6],P=99991,tot=0,head[100010];
struct List{
    int *snow;
    int nxt;
}li[100010];

int Hash(int *x)
{
    int sum=0,mul=1;
    for(int i=0;i<6;i++)
    {
        sum=((LL)sum+x[i])%P;
        mul=((LL)mul*x[i])%P;
    }
    return (sum+mul)%P;
}

bool Equal(int *a,int *b)
{
    for(int i=0;i<6;i++)
    {
        for(int j=0;j<6;j++)
        {
            bool eq=true;
            for(int k=0;k<6;k++) if(a[(i+k)%6]!=b[(j+k)%6]) eq=false;  //同方向枚举判断是否是同一片雪花 
            if(eq==true) return true;
            eq=true;
            for(int k=0;k<6;k++) if(a[(i+k)%6]!=b[(j-k+6)%6]) eq=false; // 反方向枚举 
            if(eq==true) return true;
        }
    }
    return false;
}

bool Insert(int *x)
{
    int ha=Hash(x);
    for(int i=head[ha];i;i=li[i].nxt)
    {
        if(Equal(li[i].snow,x)) return false;
    }
    tot++;
    li[tot].snow=x;
    li[tot].nxt=head[ha];
    head[ha]=tot;
    return true;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<6;j++) scanf("%d",&s[i][j]);
        if(!Insert(s[i]))
        {
            printf("Twin snowflakes found.
");
            return 0;
        }
    }
    printf("No two snowflakes are alike.
");
    return 0;
}
原文地址:https://www.cnblogs.com/BakaCirno/p/11303649.html