雪花雪花雪花

题目描述

有 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.

Solution:

字符串的最小表示:

void get_min(int a[])
{
    int b[N]={0};
    for(int i=0;i<2*n;++i)b[i]=a[i%N];
	
    int i=0,j=1,k;
    while(i<n && j<n)
    {
        for(k=0;k<n && b[i+k]==b[j+k];++k);
        if(k==n)break;
        if(b[i+k]<b[j+k])
        {
            j+=k+1;
            if(i==j)++j;
        }
        else
        {
            i+=k+1;
            if(i==j)++i;
        }
    }
    k=min(i,j);
    for(int i=0;i<n;++i)a[i]=b[i+k];
}

Code:

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int N=100005;

int n;
int s[N][6],idx[N];

void get_min(int a[])
{
    int b[12]={0};
    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])
        {
            j+=k+1;
            if(i==j)++j;
        }
        else
        {
            i+=k+1;
            if(i==j)++i;
        }
    }
    k=min(i,j);
    for(int i=0;i<6;++i)a[i]=b[i+k];
}
bool comp(int a[6],int b[6])
{
    for(int i=0;i<6;++i)
        if(a[i]<b[i])return 1;
        else if(a[i]>b[i])return 0;
    return 0;
}
bool cmp(int a,int b)
{
    return comp(s[a],s[b]);
}
int main()
{
    scanf("%d",&n);

    int a[6],b[6];
    for(int i=1;i<=n;++i)
    {
        for(int j=0,k=5;j<6;++j,--k)
        {
            scanf("%d",&a[j]);
            b[k]=a[j];
        }
        get_min(a);
        get_min(b);
        if(comp(a,b))memcpy(s[i],a,sizeof a);
        else memcpy(s[i],b,sizeof b);
        idx[i]=i;
    }

    sort(idx+1,idx+n+1,cmp);

    bool flag=0;
    for(int i=1;i<n;++i)
        if(!comp(s[idx[i]],s[idx[i+1]]) && !comp(s[idx[i+1]],s[idx[i]]))
        {
            flag=1;
            break;
        }
    if(flag)puts("Twin snowflakes found.");
    else puts("No two snowflakes are alike.");
    return 0;
}
posted @ 2022-10-18 22:02  FighterQ  阅读(161)  评论(0)    收藏  举报