题目链接:http://poj.org/problem?id=3349
题目大意:给出一系列数列,每一行数列描述的是雪花的每一个雪花臂的长度,要求判断这一系列雪花有没有相同的(只要对应位置雪花臂等长即可,顺时针和逆时针都可以)。
解题思路:由于数据量太大(最多会有100000行数列),若采用两重for循环比较的方式,复杂度为O(n^2),一定会超时,因此采用哈希表进行存储,计算每一个序列的hash值,根据该hash值决定数列存储位置,若hash值不同,可以认为雪花一定不相同,这样一来,可以只比较hash值相同的雪花序列,比较的次数大大减少。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define mod 14997
typedef struct{
int a[6];
}Node;
Node node[15000][100];
int index[15000];
int gethash(Node n)
{
int prime=0;
for(int i=0;i<6;i++)
{
prime += n.a[i]%mod;
}
prime %= mod;
return prime;
}
bool cmp(Node x,Node y)
{
int i,j;
//向右比较
for(int beginn=0;beginn<6;beginn++)
{
for(i=beginn,j=0;j<6;j++,i=(i+1)%6)
{
if(x.a[i]!=y.a[j])break;
}
if(j>=6)return true;
}
//向左比较
for(int beginn=0;beginn<6;beginn++)
{
for(i=beginn,j=0;j<6;j++,i=(i+5)%6)
{
if(x.a[i]!=y.a[j])break;
}
if(j>=6)return true;
}
return false;
}
int main()
{
int n;
scanf("%d",&n);
memset(index,0,sizeof(index));
while(n--)
{
Node input;
for(int i=0;i<6;i++)
{
scanf("%d",&input.a[i]);
}
int hashvalue = gethash(input);
for(int i=0;i<index[hashvalue];i++)
{
bool flag = cmp(input,node[hashvalue][i]);
// cout<<flag<<endl;
if(flag)
{
printf("Twin snowflakes found.\n");
return 0;
}
}
node[hashvalue][index[hashvalue]] = input;
index[hashvalue]++;
}
printf("No two snowflakes are alike.\n");
return 0;
}