poj 3349 snowflake 哈希表

有n片雪花,每片雪花有6条臂。已知每片雪花每条臂的长度。如果两片雪花的各个臂的长度对应相等,则称这两片雪花是相同的。要求判断是否存在完全相同的雪花。需要注意臂长可能是按顺时针或者逆时针顺序给出的,并且可以从任意一个臂开始。比如说,{1 2 3 4 5 6}和{ 4 3 2 1 6 5}是相同的。

注意到0<n<=100000,臂长范围在(0,10000000]。直接比较的话复杂度是O(n^2),肯定会超时。考虑用哈希表,把6个臂长加起来,模一个很大的素数,所得结果作为一个数组的下标。用链表解决地址冲突问题。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#define LOCAL
#define PRIME 124567//换做更大的3214567运行时间并未改善。
//哈希表

struct snowflake
{
    int arms[6];
    struct snowflake *next;
};
struct snowflake *a[PRIME];

int judge(struct snowflake *p,struct snowflake *q)
{
    int i;
    for(i=0;i<6;i++)
    {
        if(p->arms[0] == q->arms[i]
           && p->arms[1] == q->arms[(1+i)%6]
           && p->arms[2] == q->arms[(2+i)%6]
           && p->arms[3] == q->arms[(3+i)%6]
           && p->arms[4] == q->arms[(4+i)%6]
           && p->arms[5] == q->arms[(5+i)%6] )
            return 1;
        if(p->arms[5] == q->arms[i]
           && p->arms[4] == q->arms[(1+i)%6]
           && p->arms[3] == q->arms[(2+i)%6]
           && p->arms[2] == q->arms[(3+i)%6]
           && p->arms[1] == q->arms[(4+i)%6]
           && p->arms[0] == q->arms[(5+i)%6] )
            return 1;
    }
    return 0;
}

int ins(struct snowflake *p)
{
    int index,i;
    struct snowflake *q;
    for(i=0;i<6;i++)
    {
        index += p->arms[i];
    }
    index %= PRIME;
    q = a[index];
    while(NULL != q)
    {
        if(judge(p,q))
            return 1;
        q = q->next;
    }
    p->next =a[index];
    a[index] = p;
    return 0;
}


int main()
{
    int n,i,j,flag;
    struct snowflake *p;
    #ifdef LOCAL
    if(NULL == freopen("t.txt","r",stdin))
        printf("error redirecting\n");
    #endif
    scanf("%d",&n);
    flag = 0;
    for(i=0;i<n;i++)
    {
        p = (struct snowflake*)malloc(sizeof(struct snowflake));
        for(j=0;j<6;j++)
        {
            scanf("%d",&(p->arms[j]));
        }
        p->next = NULL;
        flag = ins(p);
        if(1 == flag)
        {
            printf("Twin snowflakes found.\n");
            break;
        }
    }
    if(0 == flag)
        printf("No two snowflakes are alike.\n");
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值