poj——3349 哈希加模拟

题目难点在于对两片雪花的比较,哈希可以加快搜索速度,防止超时,而对于如何逆时针和顺时针比较雪花是否相同便成为重点。

在这里给出两条公式:

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

  

posted @ 2017-09-08 10:27  Mr.Struggle  阅读(122)  评论(0编辑  收藏  举报