循环字符串的最小表示法的问题可以这样描述:
对于一个字符串S,求S的循环的同构字符串S’中字典序最小的一个。
由于语言能力有限,还是用实际例子来解释比较容易:
设S=bcad,且S’是S的循环同构的串。S’可以是bcad或者cadb,adbc,dbca。而且最小表示的S’是adbc。
对于字符串循环同构的最小表示法,其问题实质是求S串的一个位置,从这个位置开始循环输出S,得到的S’字典序最小。
原理:https://blog.csdn.net/cclsoft/article/details/5467743
#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
using namespace std;
int minpos(string str,int len)
{
int i=0,j=1,k=0,t;
while(i<len&&j<len&&k<len){
t=str[(i+k)>=len?i+k-len:i+k]-str[(j+k)>=len?j+k-len:j+k];
if(!t)k++;
else{
if(t>0)i=i+k+1;//这里改成t<0就是最大表示法
else j=j+k+1;
if(i==j){
++j;
}
k=0;
}
}
return min(i,j);
}
int main()
{
int t,len,i,j;string str;
cin>>t;
while(t--){
cin>>len>>str;
cout<<minpos(str,len)<<endl;
}
return 0;
}