CH1807 Necklace

题意

背景

有一天,袁☆同学绵了一条价值连城宝石项链,但是,一个严重的问题是,他竟然忘记了项链的主人是谁!在得知此事后,很多人向☆同学发来了很多邮件,都说项链是自己的,要求他归还(显然其中最多只有一个人说了真话)。 ☆同学要求每个人都写了一段关于自己项链的描述: 项链上的宝石用数字0至9来标示。一个对于项链的表示就是从项链的某个宝石开始,顺指针绕一圈,沿途记下经过的宝石,比如如下项链: 1-2-3-4 它的可能的四种表示是0123、1230、2301、3012。 袁☆同学现在心急如焚,于是他找到了你,希望你能够编一个程序,判断两个给定的描述是否代表同一个项链(注意,项链是不会翻转的)。。

描述

给定两个项链的表示,判断他们是否可能是一条项链。

输入格式

输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的)。

输出格式

如果两条项链不可能同构,那么输出’No’,否则的话,第一行输出一个’Yes’,第二行输出该项链的字典序最小的表示。

样例输入

2234342423
2423223434

样例输出

Yes
2234342423

数据范围与约定

设L = 项链长度, 对于50%的数据L <= 100000; 对于100%的数据L <= 1000000。

分析

最小表示法的运用。

时间复杂度\(O(L)\)

代码

#include<bits/stdc++.h>
using namespace std;
char a[2000010],b[2000010];
int calc_min(char s[]){
    int n=strlen(s+1);
    for(int i=1;i<=n;++i) s[n+i]=s[i];
    int i=1,j=2,k;
    while(i<=n&&j<=n){
        for(k=0;k<=n&&s[i+k]==s[j+k];++k);
        if(k==n) break;
        if(s[i+k]>s[j+k]){
            i=i+k+1;
            if(i==j) ++i;
        }
        else{
            j=j+k+1;
            if(i==j) ++j;
        }
    }
    return min(i,j);
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    scanf("%s",a+1);
    int n=strlen(a+1),x=calc_min(a);
    scanf("%s",b+1);
    int m=strlen(b+1),y=calc_min(b);
    a[x+n]=b[y+m]=0;
    if(n==m&&!strcmp(a+x,b+y)){
        puts("Yes"),puts(a+x);
    }
    else puts("No");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/autoint/p/10418275.html