http://poj.org/problem?id=3349
题目大意:
给你n个6条边的雪花的信息,问这些雪花当中是否有相同的一对。
相同的定义是:长度相同,且符合相同的顺序(顺时针或者逆时针),比如1 2 3 4 5 6是a雪花的6边信息,那么相同的雪花共有12种情况,就是按照顺时针和逆时针和a雪花边相等且顺序相同。如顺时针可以是:2 3 4 5 6 1或者3 4 5 6 1 2。逆时针可以是6 5 4 3 2 1 或者4 3 2 1 6 5.
题解:将每个雪花哈希映射到表中,如果出现冲突则判断是否出现了雪花相同的情况,没有则用拉链法解决冲突。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const double eps=1e-8;
const double INF=1e50;
//const double pi=acos(-1);
#define N 10007
struct ss
{
int a[7];
}b;
vector<struct ss>p[N];
int n;
int c[20],c1[20];
bool find()
{
int i,j;
for (i=1;i<=7;i++)
if (c[i]==c1[1])
{
for (j=2;j<=6;j++)
if (c[i+j-1]!=c1[j]) break;
if (j==7) return true;
}
return false;
}
bool check(int x)
{
int i,j,k;
for (i=0;i<p[x].size();i++)
{
for (j=1;j<=6;j++)
{c[j]=p[x][i].a[j];c1[j]=b.a[j];}
for (j=1;j<=6;j++) c[j+6]=p[x][i].a[j];
if (find()==true) return false;
for (j=1;j<=3;j++)
{
k=c1[j];
c1[j]=c1[6-j+1];
c1[6-j+1]=k;
}
if (find()==true) return false;
}
return true;
}
int main()
{
freopen("a","r",stdin);
int i,hash,j,k;
scanf("%d\n",&n);
bool flag=true;
for (k=1;k<=n;k++)
{
hash=0;
for (i=1;i<=6;i++)
{
scanf("%d",&b.a[i]);
hash+=b.a[i];
hash%=N;
}
if (p[hash].size()==0) p[hash].push_back(b);
else if (check(hash)==true) p[hash].push_back(b);
else
{
flag=false;
break;
}
}
for (j=k;j<=n;j++)
for (i=1;i<=6;i++) scanf("%d",&b.a[i]);
if (flag==true) printf("No two snowflakes are alike.\n");
else printf("Twin snowflakes found.\n");
return 0;
}