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