题意:给n个长度为6的序列环,求是否有相同的环,能通过旋转和翻面而重合则相同。即顺时针或逆时针序列相同。
思路:直接暴力两两比较的话,时间复杂度O(6*6*n*n)超时了,用hash表牺牲内存来减少时间复杂度,没学过hash表的同学可以看这个博客,http://kb.cnblogs.com/page/189480/
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
const int maxn = 100000+10;
const int mod = 10997;
typedef struct
{
int a[6];
}node;
vector<node> arr[mod+1];
int getHash(node y)
{
int value = 0;
for(int i = 0;i<6;i++)
{
value += y.a[i]%mod;
value %= mod;
}
return value;
}
bool cmp(node x,int value)
{
for(int i = 0;i<arr[value].size();i++)
{
for(int j = 0;j<6;j++)
{
int k;
int l = 0;
for(k = 0;k<6;k++)
{
if(arr[value][i].a[l++]!=x.a[(k+j)%6])
break;
}
if(k==6)
return true;
l = 0;
for(k = 5;k>=0;k--)
{
if(arr[value][i].a[l++]!=x.a[(k+j)%6])
break;
}
if(k==-1)
return true;
}
}
return false;
}
int main()
{
int n;
scanf("%d",&n);
int gg = 0;
for(int i = 0;i<n;i++)
{
node tem;
for(int j = 0;j<6;j++)
{
scanf("%d",&tem.a[j]);
}
if(gg)
continue;
int hashValue = getHash(tem);
if(cmp(tem,hashValue))
{
gg = 1;
}
arr[hashValue].push_back(tem);
}
if(gg)
printf("Twin snowflakes found.");
else
printf("No two snowflakes are alike.");
return 0;
}