BZOJ1398: Vijos1382寻找主人 Necklace 字符串最小表示法
Description
给定两个项链的表示,判断他们是否可能是一条项链。
Input
输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的)。
Output
如果两条项链不可能同构,那么输出’No’,否则的话,第一行输出一个’Yes’
第二行输出该项链的字典序最小的表示。 设L = 项链长度,L <= 1000000。
Sample Input
2234342423
2423223434
2423223434
Sample Output
Yes
2234342423
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 ; }