http://poj.org/problem?id=3349
题目描述:找是否有两片完全相同的雪花,雪花总数为 0 < n ≤ 100000,判断两片雪花是否相同的标准为其中一片雪花的的六角数组经过向左(右)循环移位后与另一片的六角数组相同
#pragma warning (disable:4786)
#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
#define rem 149991
bool flag = false; //是否有重复的数
int hash_table[150000]; //开放定址法解决冲突的哈希表
int snow[100005][6]; //雪花
哈希函数
int hash( int k ){
int sum = 0;
// for( i = 0; i < 6; i ++ )
// sum = sum + lens[i];
sum = (snow[k][0] + snow[k][2] + snow[k][4])^(snow[k][1] + snow[k][3] + snow[k][5]);
return sum % rem;
}
判断两片雪花是否相同,即其中一片雪花的的六角数组经过向左(右)循环移位后与另一片的六角数组相同
bool judge( int idx1, int idx2 ){
int i,j;
for( i =0; i < 6; i ++ )
{
if( snow[idx1][0] == snow[idx2][i] )
{
for( j = 1; j < 6; j ++ )
if( snow[idx1][j] != snow[idx2][( j + i) % 6] )
break;
if( j == 6 ) return 1;
for( j = 1; j < 6; j ++ )
if( snow[idx1][6 - j] != snow[idx2][( i + j ) % 6] )
break;
if( j == 6 ) return 1;
}
}
return 0;
}
int main(){
int i,j,n;
scanf( "%d", &n );
for(i=1;i<=n;i++)
{
for(j=0;j<=5;j++)
scanf( "%d", &snow[i][j] );
int index = hash( i );
int index1 = index;
每次查找下一个地址时的间隔
int increse = 1;
while( hash_table[index1] !=0 ){
if( judge( i , hash_table[index1] ) ){
flag = true;
break;
}
/开放定址法
index1 = ( index + increse * increse ) % rem;
increse ++;
}
hash_table[index1] = i;
}
if( ! flag )
printf("No two snowflakes are alike.\n");
else
printf("Twin snowflakes found.\n");
return 0;
}