1. 程式人生 > >poj——3349 哈希加模擬

poj——3349 哈希加模擬

cpp null div break def ash next n) type

題目難點在於對兩片雪花的比較,哈希可以加快搜索速度,防止超時,而對於如何逆時針和順時針比較雪花是否相同便成為重點。

在這裏給出兩條公式:

設i為A、B的第i片葉子,j為B當前順時針轉過的格數

那麽 A(i) ---> B( (i+j)%6 )

設i為A、B的第i片葉子,j為B當前逆時針轉過的格數

那麽 A(i) ---> B( (5-i-j+6)%6 )

#include <iostream>
using namespace std;

#define mod 999983

typedef struct Hashtable {
	int arm[6];
	struct Hashtable * next;
}Hashtable;

int Hash(int a[]){
	int key=0;
	for (int i = 0; i<6; i++)
		key += a[i] % mod;
	return key%mod;
}

Hashtable hash1[mod];

void init(){
	for (int i = 0; i<mod; i++)
		hash1[i].next = NULL;
}

bool clock(int a[], int b[]){
	for (int i = 0; i<6; i++){
		bool flag = true;
		for (int j = 0; j<6; j++){
			if (a[j] != b[(i + j) % 6]){
				flag = false;
				break;
			}
		}
		if (flag)
			return true;
	}
	return false;
}

bool opposite(int a[], int b[]){
	for (int i = 0; i<6; i++){
		bool flag = true;
		for (int j = 0; j<6; j++){
			if (a[j] != b[(5 - i - j + 6) % 6]){
				flag = false;
				break;
			}
		}
		if (flag)
			return true;
	}
	return false;
}
int main(){
	int n;
	scanf("%d", &n);
	init();
	int snow[6];
	bool a = false;
	bool b = false;
	for (int i = 0; i<n; i++){
		for (int j = 0; j<6; j++)
			scanf("%d", &snow[j]);
		int key = Hash(snow);
		Hashtable * node=new Hashtable;
		if (hash1[key].next == NULL){
			hash1[key].next = node;
			node->next = NULL;
			for (int x = 0; x<6; x++)
				node->arm[x] = snow[x];
		}
		else{
			node->next = hash1[key].next;
			hash1[key].next = node;
			for (int x = 0; x<6; x++)
				node->arm[x] = snow[x];
			Hashtable * p = node;
			while (p->next != NULL){
				p = p->next;
				a = clock(p->arm, snow);
				b = opposite(p->arm, snow);
				if (a || b){
					printf("Twin snowflakes found.\n");
					return 0;
				}
			}
		}
	}
	if (!a&&!b)
		printf("No two snowflakes are alike.\n");
	return 0;
}

  

poj——3349 哈希加模擬