#include <iostream>
#include <cstring>
using namespace std;
const int N = 2000010;
int n;
char a[N], b[N];
int get_min(char s[]) {
int i = 0, j = 1;
while (i < n && j < n) {
int k = 0;
while (k < n && s[i + k] == s[j + k]) k++;
if (s[i + k] > s[j + k]) i += k + 1;
else j += k + 1;
if (i == j) i++;
}
int k = min(i, j);
s[k + n] = '\0';//找到起始位置后,右边边界赋为0。比较到这个位置会挺
return k;//k就是最小表示法的起始位置
}
/*把字符赋为0,和赋为'\0' 效果是一样的*/
/*但是赋值97 和 赋值'a' 效果就不一样*/
int main() {
scanf("%s%s", a, b);
n = strlen(a);
memcpy(a + n, a, n);
memcpy(b + n, b, n);
int x = get_min(a), y = get_min(b);//分别得到两者的最小表示法的起始位置
//利用的原理就是,如果最小表示法相同,那么两者一定循环同构
if (strcmp(a + x, b + y)) puts("No");
else {
puts("Yes");
puts(a + x);
}
return 0;
}
下面贴了两个,分别是最大小表示法
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 1e5+9;
char str[MAX_N] = "56472819";
int getMin(char * str)
{
int len = strlen(str);
int i=0,j=1;
int k;
while(i<len && j<len)
{
for(k=0;k<len;k++)
{
if(str[(i+k) % len] != str[(j+k) % len]) break;
}
if(k >= len ) break;
if(str[(i+k) % len] > str[(j+k) % len] )
{
if(i+k+1 > j) i = i+k+1;
else i = j+1;
}
else if(j+k+1 > i) j = j+k+1;
else j = i+1;
}
return i<j?i:j;
}
int getMax(char * str)
{
int len = strlen(str);
int i =0,j=1;
int k;
while(i<len && j<len)
{
for(k=0;k<len;k++)
{
if(str[(i+k)%len] != str[(j+k)%len] ) break;
}
if(k >= len) break;
if(str[(i+k) % len] < str[(j+k) % len])
{
if(i+k+1 > j) i = i+k+1;
else i = j+1;
}
else if(j+k+1 > i) j = j+k+1;
else j = i+1;
}
return i<j?i:j;
}
int main()
{
cout<<getMin(str)<<endl;
cout<<getMax(str)<<endl;
}
标签:char,最大,int,最小,len,else,表示法,str
From: https://www.cnblogs.com/yzzyang/p/18151585