题意
给出一个字符串,求这个字符串经过移动后—最小字典序的字符串的首字符位置和出现次数, 以及 字典序最大的字符串的首字符位置和出现次数.
题解
模板:
函数返回一个位置,从这个位置开始循环输出S,得到的S’字典序最小。
int getMin ( char* str ) {
int i = 0, j = 1, k = 0;
int slen = strlen( str );
while ( i<slen && j<slen && k<slen ) {
int tmp = str[(i+k)%slen] - str[(j+k)%slen];
if ( tmp == 0 ) k++;
else {
if ( tmp > 0 ) i =i+k+1;
else j = j+k+1;
if ( j == i ) j++;
k = 0;
}
}
return min( i, j );
}
同理,求最大表示法只是把大于等于号的内容改一下
int getMax ( char* str ) {
int i = 0, j = 1, k = 0;
int slen = strlen( str );
while ( i<slen && j<slen && k<slen ) {
int tmp = str[(i + k) % slen] - str[(j+k)%slen];
if ( tmp == 0 ) k++;
else {
if ( tmp > 0 ) j =j+k+1;
else i = i+k+1;
if ( i == j ) j++;
k = 0;
}
}
return min( i, j );
}
代码
#include <bits/stdc++.h>
using namespace std;
#define rg register
#define sc scanf
#define pf printf
const int MAXN = 1e6+10;
int nxt[MAXN];
char str[MAXN];
int k;
void getNext ( char T[], int len ) {
int i = 0, j = -1;
nxt[0] = -1;
while ( i < len ) {
if ( j == -1 || T[i] == T[j] ) {
i++, j++;
nxt[i] = j;
}
else
j = nxt[j];
}
}
int get_minstring ( char* s ) { //最小表示法
int len = strlen ( s );
int i = 0, j = 1, k = 0;
while ( i < len && j < len && k < len ) {
int t = s[(i + k) % len] - s[(j + k) % len];
if ( t == 0 )
k++;
else {
if ( t > 0 )
i += k + 1;
else
j += k + 1;
if ( i == j ) j++;
k = 0;
}
}
return min ( i, j );
}
int get_maxstring ( char* s ) { //最大表示法
int len = strlen ( s );
int i = 0, j = 1, k = 0;
while ( i < len && j < len && k < len ) {
int t = s[(i + k) % len] - s[(j + k) % len];
if ( t == 0 )
k++;
else {
if ( t > 0 )
j += k + 1;
else
i += k + 1;
if ( i == j ) j++;
k = 0;
}
}
return min ( i, j );
}
int main ( ) {
while ( sc( "%s", str ) != EOF ) {
int len = strlen ( str );
getNext ( str, len );
int tt = len-nxt[len];
int num = 1;
if ( len % tt == 0 ) {
num = len/tt;
}
int posmin = get_minstring ( str );
int posmax = get_maxstring ( str );
pf( "%d %d %d %d\n", posmin+1, num, posmax+1, num );
}
return 0;
}
下面附上天真的超时代码 --_–
// #include <bits/stdc++.h>
// using namespace std;
// #define rg register
// #define sc scanf
// #define pf printf
// int main ( ) {
// set<char> st;
// int sum[300];
// int pos[300];
// string s;
// while ( cin >> s ) {
// st.clear();
// memset( sum, 0, sizeof(sum) );
// memset( pos, 0, sizeof(pos) );
// rg int len = s.size( );
// for ( rg int i = 0; i < len; ++i ) {
// st.insert( s[i] );
// if ( sum[s[i]] == 0 ) pos[s[i]] = i+1;
// sum[s[i]]++;
// }
// set<char>::iterator itMin = st.begin();
// // set<char>::reverse_iterator itMax = st.end();
// set<char>::iterator itMax = st.end();
// itMax--;
// // cout << *st.rbegin() << " " << *st.rend() << endl;
// cout << pos[*itMin] << " " << sum[*itMin] << " " << pos[*itMax] << " " << sum[*itMax] << endl;
// }
// return 0;
// }