137. 雪花雪花雪花 hash表

这是一个关于算法实现的问题,程序旨在检测给定的N片雪花中是否存在两片形状相同。每片雪花由六个角组成,每个角都有长度,通过比较不同排列组合来判断形状是否相同。程序首先读取雪花数量N,然后读取每片雪花的角长度,利用哈希函数和自定义的检查函数来检查形状,最后根据结果输出是否找到形状相同的雪花。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有 N 片雪花,每片雪花由六个角组成,每个角都有长度。

第 i 片雪花六个角的长度从某个角开始顺时针依次记为 ai,1,ai,2,…,ai,6。

因为雪花的形状是封闭的环形,所以从任何一个角开始顺时针或逆时针往后记录长度,得到的六元组都代表形状相同的雪花。

例如 ai,1,ai,2,…,ai,6 和 ai,2,ai,3,…,ai,6,ai,1 就是形状相同的雪花。

ai,1,ai,2,…,ai,6 和 ai,6,ai,5,…,ai,1 也是形状相同的雪花。

我们称两片雪花形状相同,当且仅当它们各自从某一角开始顺时针或逆时针记录长度,能得到两个相同的六元组。

求这 N 片雪花中是否存在两片形状相同的雪花。

输入格式
第一行输入一个整数 N,代表雪花的数量。

接下来 N 行,每行描述一片雪花。

每行包含 6 个整数,分别代表雪花的六个角的长度(这六个数即为从雪花的随机一个角顺时针或逆时针记录长度得到)。

同行数值之间,用空格隔开。

输出格式
如果不存在两片形状相同的雪花,则输出:

No two snowflakes are alike.

如果存在两片形状相同的雪花,则输出:

Twin snowflakes found.

数据范围
1≤N≤100000,
0≤ai,j<10000000

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int  mod =99991;
struct node {
	int s[7];
} now1, now2;
int a[100];
vector<node>v[100011];
int h(int a[]) {
	int sum = 0;
	int mul = 1;
	for (int i = 0; i < 6; i++) {
		sum = (sum + a[i]) % mod;
		mul = ((ll)mul * a[i]) % mod;
	}

	return (sum + mul) % mod;
}
bool check(node a, int b[]) {
	for (int i = 0; i < 6; i++) {
		for (int j = 0; j < 6; j++) {
			bool f = 1;
			for (int k = 0; k < 6; k++) {

				if (a.s[(i + k)% 6 ] != b[(j + k) % 6])f = 0;
			}
			if (f == 1)
				return 1;
			f = 1;
			for (int k = 0; k < 6; k++) {
				if (a.s[(k + i) % 6] != b[(j - k + 6) % 6])f = 0;
			}
			if (f == 1)
				return 1;
		}
	}
	return 0;
}
int main() {
	int n, f = 0,e;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < 6; j++) {
			cin >> a[j];
		}
		e=h(a);
		//cout << "h " << e << endl;
		if (v[e].size()) {
			for (auto it : v[e]) {
				if (check(it, a)) {
					f = 1;
				} else {
					for (int i = 0; i < 6; i++) {
						now1.s[i] = a[i];
					}
					v[e].push_back(now1);
				}
			}
		} else {
			for (int i = 0; i < 6; i++) {
				now1.s[i] = a[i];
			}
			v[e].push_back(now1);
		}
	}
	if (f == 0)
		cout << "No two snowflakes are alike.";
	else
		cout << "Twin snowflakes found.";
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值