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