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;
}

你可能感兴趣的:(poj)