poj-3349 Snowflake Snow Snowflakes *
/*
* hash。。 链表法
* 3349.cpp
*
* 需注意如何判断两个雪花一样
* 看数据:
* 1 1 2 0 0 0
* 1 1 0 0 0 2
*
* Created on: 2011-7-21
* Author:
*/
#include <cstdio>
using namespace std;
const int MAXN = 100000 + 5;
int n;
bool vis[MAXN] = {};
struct SData{
int a[6];
SData *pre, *next;
};
SData *table[MAXN];
SData snow[MAXN];
//相加 % MAXN
int hash(SData *d){
int ans = 0;
for(int i=0; i<6; i++)
ans += d->a[i];
return ans % MAXN;
}
bool search(SData *t, SData *b){
while(t != NULL){
int i = -1, j;
while(i < 6){
i++;
for(; i<6 && t->a[i]!=b->a[0]; i++);
for(j=0; j<6; j++)
if(t->a[(i+j) % 6] != b->a[j % 6]) break;
if(j == 6) return true;
for(j=0; j<6; j++)
if(t->a[(i+6-j) % 6] != b->a[j % 6]) break;
if(j == 6) return true;
}
t = t->next;
}
return false;
}
int main(){
bool flag = 0;
scanf("%d", &n);
for(int i=0; i<n; i++){
for(int j=0; j<6; j++)
scanf("%d", &snow[i].a[j]);
int h = hash(&snow[i]);
if(!vis[h]){
vis[h] = 1;
table[h] = &snow[i];
snow[i].next = NULL;
}
else if(search(table[h], &snow[i])){
flag = 1;
}
else{
snow[i].next = table[h];
table[h] = &snow[i];
}
}
if(flag)
printf("Twin snowflakes found.\n");
else
printf("No two snowflakes are alike.\n");
return 0;
}
【另附 开放寻址法】
/*
* hash。。 开放寻址法(效率似乎没链表法高)
* 3349.cpp
*
* 需注意如何判断两个雪花一样
* 看数据:
* 1 1 2 0 0 0
* 1 1 0 0 0 2
*
* Created on: 2011-7-21
* Author:
*/
#include <cstdio>
using namespace std;
const int MAXN = 1 << 18;
int n;
bool vis[MAXN] = {};
struct SData{
int a[6];
};
SData table[MAXN];
SData snow;
int inline hash1(SData *d){
int ans = 0;
for(int i=0; i<6; i++)
ans += d->a[i];
return ans;
}
int inline hash2(SData *d){
return 2 * ((d->a[0] + d->a[2] + d->a[4])&(d->a[1] + d->a[3] + d->a[5])) + 1;
}
//双重散列
int inline hash(SData *d, int k){
//MAXN为2的幂,hash2总产生素数,故hash2与MAXN互素,确保能遍历hash_table
return (hash1(d) + k * hash2(d)) % MAXN;
}
bool check(SData *t, SData *b){
int i = -1, j;
while(i < 6){
i++;
for(; i<6 && t->a[i]!=b->a[0]; i++);
for(j=0; j<6; j++)
if(t->a[(i+j) % 6] != b->a[j % 6]) break;
if(j == 6) return true;
for(j=0; j<6; j++)
if(t->a[(i+6-j) % 6] != b->a[j % 6]) break;
if(j == 6) return true;
}
return false;
}
bool hash_insert(SData *d){
int i, j;
for(i=0; i<MAXN; i++){
j = hash(d, i);
if(!vis[j]){
vis[j] = 1;
table[j] = *d;
return 0;
}
else if(check(&table[j], d))
return 1;
}
}
int main(){
bool flag = 0;
scanf("%d", &n);
for(int i=0; i<n; i++){
for(int j=0; j<6; j++)
scanf("%d", &snow.a[j]);
if(hash_insert(&snow))
flag = 1;
}
if(flag)
printf("Twin snowflakes found.\n");
else
printf("No two snowflakes are alike.\n");
return 0;
}