浏览器标题切换
浏览器标题切换end
把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

BZOJ1398: Vijos1382寻找主人 Necklace 字符串最小表示法

Description

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

Input

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

Output

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

Sample Input

2234342423
2423223434

Sample Output

Yes
2234342423

Solution

最小表示法板子题...随便跑一跑就行

#include <bits/stdc++.h>

using namespace std ;

#define N 2000100
#define inf 0x3f3f3f3f

char s1[ N ] , s2[ N ] ;
int cur1 , cur2 ;

int main() {
    scanf( "%s%s" , s1 + 1 , s2 + 1 ) ;
    int n = strlen( s1 + 1 ) ;
    for( int i = 1 ; i <= n ; i ++ ) {
        s1[ i + n ] = s1[ i ] ;
        s2[ i + n ] = s2[ i ] ;
    }
    int i = 1 , j = 2 , k ;
    while( i <= n && j <= n ) {
        for( k = 0 ; k <= n && s1[ i + k ] == s1[ j + k ] ; k ++ ) ;
        if( k == n ) break ;
        if( s1[ i + k ] > s1[ j + k ] ) {
            i = i + k + 1 ;
            if( i == j ) i ++ ;
        } else {
            j = j + k + 1 ;
            if( i == j ) j ++ ;
        }
    }
    cur1 = min( i , j ) ;
    i = 1 , j = 2 , k = 0 ;
    while( i <= n && j <= n ) {
        for( k = 0 ; k <= n && s2[ i + k ] == s2[ j + k ] ; k ++ ) ;
        if( k == n ) break ;
        if( s2[ i + k ] > s2[ j + k ] ) {
            i = i + k + 1 ;
            if( i == j ) i ++ ;
        } else {
            j = j + k + 1 ;
            if( i == j ) j ++ ;
        }
    }
    cur2 = min( i , j ) ;
    for( int c = 0 ; c < n ; c ++ ) {
        if( s1[ cur1 + c ] != s2[ cur2 + c ] ) return puts( "No" ) , 0 ;
    }
    puts( "Yes" ) ;
    for( int c = cur1 ; c <= cur1 + n - 1 ; c ++ ) {
        putchar( s1[ c ] ) ;
    }
    puts("");
    return 0 ;
} 

 

posted @ 2018-10-24 23:06  henry_y  阅读(221)  评论(0编辑  收藏  举报