题目来源:poj 3349
题意:判断有没有两朵相同的雪花。每朵雪花有六瓣,比较花瓣长度的方法看是否是一样的,如果对应的arms有相同的长度说明是一样的。给出n朵,只要有两朵是一样的就输出有Twin snowflakes found.,如果任何两个都是不一样的输出No two snowflakes are alike。
思路:
哈希函数:除留余数法,(把余数看成链地址)取关键字被某个不大于哈希表表长m的数prime除后所得余数为哈希地址,H(key)=key MOD p (p<=m)。一般情况下,可以选择prime为质数或不包含于小于20的质因子的和数。这里取prime = 14997。
#include <iostream>
#include <vector>
using namespace std;
const int prime = 14997;
const int maxn = 100010;
int maze[maxn][6];
vector<int> hashLink[prime];
bool cmp(int a, int b) //比较两片雪花是不是相同的
{
int i, j;
for (i = 0; i < 6; i++)
{
if (maze[a][0] == maze[b][i])
{
for (j = 1; j < 6; j++)
{
if (maze[a][j] != maze[b][(i + j) % 6]) //顺时针方向比较
{
break;
}
}
if (j == 6)
{
return true;
}
for (j = 1; j < 6; j++)
{
if (maze[a][6 - j] != maze[b][(i + j) % 6])
{
break;
}
}
if (j == 6)
{
return true;
}
}
}
return false;
}
//所有的雪花数据输入后,对在hash同一槽的雪花进行两两比较
bool check()
{
for (int i = 0; i < prime; i++)
{
for (int j = 0; j < hashLink[i].size(); j++)
{
for (int k = j + 1; k < hashLink[i].size(); k++)
{
if (cmp(hashLink[i][j], hashLink[i][k]))
{
return true;
}
}
}
}
return false;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
int sum = 0;
for (int j = 0; j < 6; j++)
{
scanf("%d", &maze[i][j]);
sum += maze[i][j];
}
hashLink[sum % prime].push_back(i);
}
if (check())
{
cout << "Twin snowflakes found." << endl;
}
else
{
cout << "No two snowflakes are alike." << endl;
}
return 0;
}