http://poj.org/problem?id=3349
题目描述:找是否有两片完全相同的雪花,雪花总数为 0 < n ≤ 100000,判断两片雪花是否相同的标准为其中一片雪花的的六角数组经过向左(右)循环移位后与另一片的六角数组相同
下述方法的一个改进是用空间换取时间,即将雪花的六角存储两份在一个 size 为 12 的数组中,判断另一片要雪花数组是否在其中,然后将两一片雪花数组逆序,再判断一次、
逆序有一种较为巧妙的方法,不用辅助空间,如下
reverse( int a[] , size ){
for( int i = 1, i <= size / 2; i ++ ){
a[i] = a[i] ^ a[size - i];
a[size - i] = a[i] ^ a[size - i];
a[i] = a[i] ^ a[size - i];
}
}
#pragma warning (disable:4786)
#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
#define rem 9991 //hash时取模的大质数
bool flag = false; //是否有重复的数
雪花
struct snow{
int lens[6]; //雪花有六个角
snow * next; //使用拉链法解决哈希冲突
};
表头
struct head{
snow * next;
};
head h[rem + 1];
清空hash表
void init(){
int i;
for( i = 0; i < rem; i ++ ){
h[i].next = NULL;
}
}
哈希函数
int hash( int lens[] ){
int sum = 0;
//这种方法只适用于此题
sum = (lens[0] + lens[2] + lens[4])^(lens[1] + lens[3] + lens[5]);
// for( i = 0; i < 6; i ++ )
// sum = sum + lens[i];
return sum % rem;
}
判断两片雪花是否相同,即其中一片雪花的的六角数组经过向左(右)循环移位后与另一片的六角数组相同
bool judge( int a[], int b[] ){
int i,j;
for(i=0;i<6;i++)
{
if(a[0]==b[i])
{
for(j=1;j<6;j++)
if(a[j]!=b[(j+i)%6])
break;
if(j==6) return 1;
for(j=1;j<6;j++)
if(a[6-j]!=b[(i+j)%6])
break;
if(j==6) return 1;
}
}
return 0;
}
在链表里寻找是否有完全相同的另一片雪花,有返回true
bool search( head * h, int lens[8] ){
snow * temp = h->next;
snow * p = NULL; // p 指向当前访问链表节点的上一个节点
while( temp != NULL )
{
if( judge( lens, temp->lens ) )
return true;
p = temp;
temp = temp -> next;
}
//没有找到重复节点,则插入该节点
temp = new snow;
for( int j = 0; j < 8; j ++ )
temp->lens[j] = lens[j];
temp->next = NULL;
if( p != NULL )
p->next = temp;
else h->next = temp;
return false;
}
int main(){
int i,j,n;
init();
下面的这段读输入的程序在G++上比直接 scanf("%d",&len[j]) 的速度快一倍以上
char c;
cin>>n;
c=getchar();
for(i=1;i<=n;i++)
{
int lens[6];
for(j=0;j<=5;j++)
{
int x=0;
c=getchar();
while(c!=' '&&c!='\n')
{
x=x*10;
x+=(c-48);
c=getchar();
}
lens[j] = x;
}
读输入的程序结束
if( !flag ){
哈希并查找重复
int index = hash( lens );
flag = search( &h[index], lens );
}
}
if( ! flag )
printf("No two snowflakes are alike.\n");
else
printf("Twin snowflakes found.\n");
return 0;
}