[BZOJ1398]Vijos1382寻找主人 Necklace

1398: Vijos1382寻找主人 Necklace

Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 351  Solved: 155 [Submit][Status][Discuss]

Description

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

Input

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

Output

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

Sample Input

2234342423
2423223434

Sample Output

Yes
2234342423
 
最小表示法
然后比较一下是否相等即可
#include <cstdio>
#include <cstring> 
const int maxn = 1000000 + 10;
char s1[maxn], s2[maxn];
int fms(char *s){
    int len = strlen(s);
    int i = 0, j = 1, k = 0;
    int nxi, nxj, t;
    while(i < len && j < len && k < len){
        nxi = i + k; while(nxi >= len) nxi -= len;
        nxj = j + k; while(nxj >= len) nxj -= len;
        t = s[nxi] - s[nxj]; 
        if(t == 0) k++;
        else{
            if(t > 0) i += k + 1;
            else j += k + 1;
            if(i == j) j++;
            k = 0; 
        }
    }
    return i < j ? i : j;
}
int main(){
    scanf("%s%s", s1 + 1, s2 + 1);
    int len = strlen(s1 + 1), a = fms(s1 + 1) + 1, b = fms(s2 + 1) + 1; 
    bool flag = true;
    for(int aa = a, bb = b, i = 1; i <= len; i++){
        if(s1[aa++] != s2[bb++]){
            flag = false;
            break;
        }
        if(aa > len) aa -= len;
        if(bb > len) bb -= len;
    }
    if(flag){
        puts("Yes");
        for(int aa = a, i = 1; i <= len; i++){
            putchar(s1[aa++]);
            if(aa > len) aa -= len;
        }
    }
    else puts("No");
    return 0;
}
原文地址:https://www.cnblogs.com/ruoruoruo/p/7623335.html