有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
输入样例:
2
1 2 3 4 5 6
4 3 2 1 6 5
输出样例:
Twin snowflakes found.
算法: 字符串的最小表示法
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int snow[6],isnow[6],snows[100010][6],idx[100010];
void get_min(int *a){
int ss[12];
for (int i = 0; i <= 11; ++i)
ss[i] = a[i % 6];
int i = 0,j = 1,ans,k;
while(i < 6 && j < 6){
for (k = 0; k < 6; ++k)
if (ss[i + k] != ss[j + k]) break;
if (k == 6) break; // 注意 这里是 k == 6 而非 k == 5,当 k == 6 的时候代表的是从不同的i,j出发,经过长度为n可以找出两条相同的子串,那么一定会由更小的循环节,且此时两指针i和j一定是位于循环节相同位置的字母上
if (ss[i + k] > ss[j + k]){
i = i + k + 1;
if (i == j)
i ++;
}else if (ss[i + k] < ss[j + k]){
j = j + k + 1;
if (i == j)
j++;
}
ans = min(i,j);
}
for (int i = 0; i < 6; ++i){
a[i] = ss[i + ans];
}
}
bool cmp2(int* a,int* b){
for (int i = 0; i < 6; ++i){
if (a[i] < b[i])
return true;
else if (a[i] > b[i])
return false;
}
return false;
}
bool cmp1(int a,int b){
for (int i = 0; i < 6; ++i){
if (snows[a][i] < snows[b][i])
return true;
else if (snows[a][i] > snows[b][i])
return false;
}
return false;
}
int main(){
int n;
cin>>n;
for (int i = 0; i < n; ++i){
for (int j = 0; j < 6; ++j){
cin>>snow[j];
isnow[5 - j] = snow[j];
}
get_min(snow);
get_min(isnow);
if (cmp2(snow,isnow)){ // 如果 snow 字典序小于 isnow
memcpy(snows[i],snow,sizeof snow);
}else{
memcpy(snows[i],isnow,sizeof isnow);
}
idx[i] = i;
}
sort(idx,idx + n, cmp1);
for (int i = 1; i < n; ++i){
if (!cmp1(idx[i - 1],idx[i]) && !cmp1(idx[i],idx[i - 1])){ // cmp1(a,b) 判断是的是否 snows[a] <= snows[b]
puts("Twin snowflakes found.");
return 0;
}
}
puts("No two snowflakes are alike.");
return 0;
}