POJ3349-Snowflake Snow Snowflakes

POJ3349-Snowflake Snow Snowflakes

题目描述
Description

You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your program will read information about a collection of snowflakes, and search for a pair that may be identical. Each snowflake has six arms. For each snowflake, your program will be provided with a measurement of the length of each of the six arms. Any pair of snowflakes which have the same lengths of corresponding arms should be flagged by your program as possibly identical.

Input

The first line of input will contain a single integer n, 0 < n ≤ 100000, the number of snowflakes to follow. This will be followed by n lines, each describing a snowflake. Each snowflake will be described by a line containing six integers (each integer is at least 0 and less than 10000000), the lengths of the arms of the snow ake. The lengths of the arms will be given in order around the snowflake (either clockwise or counterclockwise), but they may begin with any of the six arms. For example, the same snowflake could be described as 1 2 3 4 5 6 or 4 3 2 1 6 5.

Output

If all of the snowflakes are distinct, your program should print the message:
No two snowflakes are alike.
If there is a pair of possibly identical snow akes, your program should print the message:
Twin snowflakes found.

Sample Input
2
1 2 3 4 5 6
4 3 2 1 6 5
Sample Output
Twin snowflakes found.

思路介绍

​ 首先,对于这道题,无论是暴力法(当然暴力没能出奇迹)还是哈希表,必不可少的一点就是判断两片雪花是否相同。根据题目要求,当这两片雪花,从某一个角起,顺时针或者逆时针读取数据后形成的序列是相同的,那么这两片雪花就是相同的。如样例,第一片为123456,第二片为432165,但是第二片从第4个角逆时针读取数据,也是123456,所以这两片雪花是相同的。我们可以通过重载‘==’运算符,进而实现这一功能。

​ 然后,就是这道题目的核心——哈希表。

哈希表

​ 哈希表是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。所谓从A到B的映射,即f:A→B,就是指,A中的任意一个元素,在B中都有唯一的值与它对应,但是,B中的一个值可能对应A中的许多元素。对于哈希表,就是从value到key的映射。如果说,我们遇到了两个不同的value,但是他们的hashcode都是相同的,我们可以让每个key对应一个链表,这样我们只需要将这两个元素,连到这个链表上,即可实现一个key对应多个value了。

​ 为了实现快速查找,我们使用哈希表。这道题中,我选择通过将雪花每边的长度相加并对99991取模——(a[0]+a[1]……+a[5])%99991。当我们算出某片雪花的hashcode的时候,先看一下这个hashcode对应的链表是否不为空,即是否存在过hashcode相同的雪花,因为如果存在两片不同的雪花,他们的hashcode可能相同,只是排列顺序不同,但是如果两片雪花的hashcode不同,那么这两片雪花必定不同,这样就可以省去多余的比较。

AC代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;

const int mod = 99991;

struct node
{
	int a[6];//用来存储每片雪花的6个边
	bool operator==(const node& temp)const
	{
		for (int i = 0; i < 6; i++)
			if ((a[0] == temp.a[i]
				&& a[1] == temp.a[(i + 1) % 6]
				&& a[2] == temp.a[(i + 2) % 6]
				&& a[3] == temp.a[(i + 3) % 6]
				&& a[4] == temp.a[(i + 4) % 6]
				&& a[5] == temp.a[(i + 5) % 6]) ||
				(a[0] == temp.a[i]
				&& a[1] == temp.a[(i + 5) % 6]
				&& a[2] == temp.a[(i + 4) % 6]
				&& a[3] == temp.a[(i + 3) % 6]
				&& a[4] == temp.a[(i + 2) % 6]
				&& a[5] == temp.a[(i + 1) % 6]))
				return true;
		return false;
	}//重载等号运算符
};

vector<node>Hash[mod];
node A[100005];

int main(void)
{
	int T;
	cin >> T;
	for (int i = 0; i < T; i++)
	{
		int sum = 0;
		for (int j = 0; j < 6; j++)
		{
			scanf("%d", &A[i].a[j]);
			sum += A[i].a[j];
		}
		sum %= mod;//计算hashcode

		for (int j=0;j<Hash[sum].size();j++)
		{
			if (Hash[sum][j] == A[i])
			{
				cout << "Twin snowflakes found.\n";
				return 0;
			}
		}
		Hash[sum].push_back(A[i]);
	}
	cout << "No two snowflakes are alike.\n";
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值