数字哈希。我用的是雪花六个角之和取模。模很大 999983,哈希表是指针数组,链地址法处理冲突。
要考虑雪花顺时针和逆时针。
//============================================================================
//
// > File : poj3349.cpp
// > Author : flowertree
// > Time : 2015年11月12日
// > Algorithm : 数字哈希
//
//============================================================================
#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
using namespace std;
#define Prime 999983
#define MAX 100005
struct snow
{
__int64 edge[6];
snow * next;
};
struct hashnode
{
snow * next;
hashnode()
{
next = NULL;
}
};
snow node[MAX];
hashnode hashtable[Prime];
int node_count = 0;
snow * getnode()
{
return &node[node_count++];
}
bool Judge(snow * a, snow * b)
{
int i, j;
int temp;
bool mark;
//顺时针
for(i = 0; i < 6; i++)
{
mark = true;
for(j = 0; j < 6; j++)
{
temp = (i + j) % 6;
if(a -> edge[temp] != b -> edge[j])
mark = false;
}
if(mark)
break;
}
if(mark)
return true;
//逆时针
for(i = 0; i < 6; i++)
{
mark = true;
for(j = 0; j < 6; j++)
{
temp = (i - j + 6) % 6;
if(a -> edge[temp] != b -> edge[j])
mark = false;
}
if(mark)
break;
}
if(mark)
return true;
else
return false;
}
int main()
{
int m;
__int64 e[6];
__int64 hashnum;
snow * temp, * p;
bool flag = false;
cin >> m;
while(m--)
{
hashnum = 0;
temp = getnode();
for(int i = 0; i < 6; i++)
{
scanf("%I64d", &e[i]);
hashnum += e[i] % Prime;
temp -> edge[i] = e[i];
}
if(flag)
continue;
hashnum = hashnum % Prime;
if(hashtable[hashnum].next == NULL)
{
hashtable[hashnum].next = temp;
temp -> next = NULL;
}
else
{
for(p = hashtable[hashnum].next; p -> next != NULL; p = p -> next)
{
flag = Judge(temp, p);
if(flag)
break;
}
if(!flag)
flag = Judge(temp, p);
if(!flag)
{
p -> next = temp;
temp -> next = NULL;
}
}
}
if(flag)
{
cout << "Twin snowflakes found." << endl;
}
else
{
cout << "No two snowflakes are alike." << endl;
}
system("pause");
return 0;
}