最小表示法 + 字符串hash
把每个雪花的正反求一次最小表示法。然后字符串hash就可以了.....
时间复杂度$O(N)$,空间复杂度$O(N)$
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const ull maxn = 1e7 + 9;
int n;
ull a[20],b[20];
int f(ull *t)
{
int i = 1,j = 2,k;
while(i <= 6 && j <= 6)
{
for(k = 0; k <= 6 && t[i + k] == t[j + k];k++);
if(k == 6) break;
if(t[i + k] > t[j + k])
{
i = i + k + 1;
if(i == j) i++;
}
else
{
j = j + k + 1;
if(i == j) j++;
}
}
return min(i,j);
}
int main()
{
unordered_map<ull,int> ump;
cin >> n;
for(int t = 1; t <= n; t++)
{
ull hash = 0;
for(int j = 1, k = 6; j <= 6; j++, k--) cin >> a[j], b[k] = a[j];
for(int j = 7; j <= 12; j++) a[j] = a[j - 6],b[j] = b[j - 6];
int k = f(a);
for(int j = 0; j < 6; j++) hash =hash*maxn+a[k + j];
if(ump.find(hash) == ump.end()) ump[hash] = 1;
else
{
cout<<"Twin snowflakes found.";
return 0 ;
}
k = f(b);hash = 0;
for(int j = 0; j < 6; j++) hash =hash*maxn+b[k + j];
if(ump.find(hash) == ump.end()) ump[hash] = 1;
else
{
cout << "Twin snowflakes found.";
return 0;
}
}
cout<<"No two snowflakes are alike.";
}
如果六个角度都相同的话,正向的哈希值存进去之后再判断反向的哈希值的时候不就误判了吗
我认为的处理方式是要对正反两次哈希值判断一下是否相等
是的,还需做一次判断
为什么正向做一遍以后还必须反向做一遍?不做答案还是错的
可能是为了减少哈希冲突?我也不太清楚
因为是顺时针和逆时针两个方向的旋转,所以还得反向做一遍
老哥map的插入、查找的时间复杂度都是log级别的吧。所以执行n次插入和查找的时间复杂度上界应该是NlogN吧。
unordered_map 是哈希表,操作都是o(1)的
谢谢
大佬,我直接用字符串正反最小表示 T了 求助%>_<%