题目描述
有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 <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int snows[N][6]; //存储每个字符串的最小表示
int idx[N];
//两个字符串比较
bool cmp_array(int a[], int b[])
{
for(int i = 0; i < 6; i++)
{
if(a[i] > b[i]) return false;
else if(a[i] < b[i]) return true;
}
return false;
}
//sort排序函数
bool cmp(int a, int b)
{
return cmp_array(snows[a], snows[b]);
}
//字符串最小表示模板
void get_min(int a[])
{
static int b[12];
for(int i = 0; i < 12; i++) b[i] = a[i % 6];
int i = 0, j = 1, k;
while(i < 6 && j < 6)
{
for(k = 0; k < 6 && b[i + k] == b[j + k]; k++);
if(k == 6) break;
if(b[i + k] > b[j + k])
{
i += k + 1;
if(i == j) i++;
}
else
{
j += k + 1;
if(i == j) j++;
}
}
k = min(i, j);
for(int i = 0; i < 6; i++) a[i] = b[i + k];
}
int main()
{
scanf("%d", &n);
int snow[6], isnow[6];
for(int i = 0; i < n; i++)
{
for(int j = 0, k = 5; j < 6; j++, k--)
{
scanf("%d", &snow[j]);
isnow[k] = snow[j];
}
get_min(snow);
get_min(isnow);
if(cmp_array(snow, isnow)) memcpy(snows[i], snow, sizeof snow);
else memcpy(snows[i], isnow, sizeof isnow);
idx[i] = i;
}
//排索引
sort(idx, idx + n, cmp);
bool flag = false;
for(int i = 1; i < n; i++)
{
//判断两个字符串是否相等
if(!cmp(idx[i - 1], idx[i]) && !cmp(idx[i], idx[i - 1]))
{
flag = true;
break;
}
}
if(flag) puts("Twin snowflakes found.");
else puts("No two snowflakes are alike.");
return 0;
}