(一)最小表示法:求环状字符串的最小字典序
首先定义两个指针分别指向字符串的位置0和位置1,依次比较从这两个位置开始的字符串的字典序的大小
*p = s[0],*q = s[1]
(1)*(p+k) == *(q+k)
比较下一位(k++)
(2)*(p+k) > *(q+k)
那么*p 开始的字符串就舍弃,移动p指针,*p = *(p+k+1)
(3)*(p+k) < *(q+k)
那么*q 开始的字符串就舍弃,移动q指针,*q = *(q+k+1)
int Min_Express(char *s) //返回最小字典序开始的位置
{
int len = strlen(s);
int i = 0,j = 1,k = 0;
while(i<len && j<len &&k<len)
{
int tep = s[(i+k)%len] - s[(j+k)%len];
if(tep==0) k++;
else
{
if(tep>0) i = i+k+1;
else j = j+k+1;
if(i==j) j++;
k = 0;
}
}
return i<j ? i:j;
}
(二)最大表示法:求环状字符串的最大字典序
首先定义两个指针分别指向字符串的位置0和位置1,依次比较从这两个位置开始的字符串的字典序的大小
*p = s[0],*q = s[1]
(1)*(p+k) == *(q+k)
比较下一位(k++)
(2)*(p+k) > *(q+k)
那么*q 开始的字符串就舍弃,移动q指针,*q = *(q+k+1)
(3)*(p+k) < *(q+k)
那么*p 开始的字符串就舍弃,移动p指针,*p = *(p+k+1)
int Max_Express(char *s) //返回最大字典序开始的位置
{
int len = strlen(s);
int i = 0,j = 1,k = 0;
while(i<len && j<len &&k<len)
{
int tep = s[(i+k)%len] - s[(j+k)%len];
if(tep==0) k++;
else
{
if(tep>0) j = j+k+1;
else i = i+k+1;
if(i==j) j++;
k = 0;
}
}
return i<j ? i:j;
}
题意:
给一个环状的字符串,求出字典序最小的字符串
题解:
最小表示法模板题
#include <cstdio>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
char str[1100];
int Min_Express(char *s)
{
int len = strlen(s);
int i = 0,j = 1,k = 0;
while(i<len && j<len &&k<len)
{
int tep = s[(i+k)%len] - s[(j+k)%len];
if(tep==0) k++;
else
{
if(tep>0) i = i+k+1;
else j = j+k+1;
if(i==j) j++;
k = 0;
}
}
return i<j ? i:j;
}
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%s",str);
printf("%d\n",Min_Express(str)+1);
}
return 0;
}