题意:
有一个len长度的环,求某一位置pos,以该点为头,其字典序最大(正逆顺序都行)。
如果有且只有一个 ,输出其 开头的下标, 下标从1 开始, 再输出0 表示顺时针 1表示逆时针
如果有多个(包括在正序与逆序),输出 开头下标最小的那个。
另外,就是顺时针 逆时针 一样且下标相等的情况 算成顺时针的。
有一个len长度的环,求某一位置pos,以该点为头,其字典序最大(正逆顺序都行)。
如果有且只有一个 ,输出其 开头的下标, 下标从1 开始, 再输出0 表示顺时针 1表示逆时针
如果有多个(包括在正序与逆序),输出 开头下标最小的那个。
另外,就是顺时针 逆时针 一样且下标相等的情况 算成顺时针的。
思路:字符串的最大表示法 + kmp,kmp针对逆序的 因为跑完最大表示法返回的是最小的合法位置,在逆时针的情况下,它的最小位置即顺时针的最大位置,我们输出的位置都是对于顺时针来说的 所以还得跑一边kmp求出逆时针的最大位置即顺时针最小位置。
字符串最大表示法算法:http://blog.csdn.net/bigsungod/article/details/41514095
代码:
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <map>
#include <set>
#define sss(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a) memset(a,0,sizeof(a))
#define ss(a,b) scanf("%d%d",&a,&b)
#define s(a) scanf("%d",&a)
#define p(a) printf("%d\n", a)
#define INF 0x3f3f3f3f
#define w(a) while(a)
#define PI acos(-1.0)
#define LL long long
#define eps 10E-9
#define N 100010
const LL mod = 1000000000+7;
const int SIGMA_SIZE=26;
const int MAXN=100010;
const int MAXNODE=600010;
using namespace std;
void mys(int& res) {
int flag=0;
char ch;
while(!(((ch=getchar())>='0'&&ch<='9')||ch=='-'))
if(ch==EOF) res=INF;
if(ch=='-') flag=1;
else if(ch>='0'&&ch<='9') res=ch-'0';
while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0';
res=flag?-res:res;
}
void myp(int a) {
if(a>9)
myp(a/10);
putchar(a%10+'0');
}
/*************************THE END OF TEMPLATE************************/
char str[N];
char cs[N];
char ccs[N];
int nt[N];
int work(int len,char pat[]) {
int i=0,j=1,k=0;
while(i<len && j<len && k<len) {
int t = pat[(i+k)%len] - pat[(j+k)%len];
if(!t) k++;
else {
if(t>0) j = j+k+1;
else i = i+k+1;
if(i == j) j++;
k = 0 ;
}
}
return i<j?i:j;
}
void next() {
int j=0,k=-1;
nt[0]=-1;
while(!j || ccs[j]!='\0') {
if(k==-1 || ccs[j]==ccs[k]) {
j++;
k++;
if(ccs[j]!=ccs[k])
nt[j]=k;
else
nt[j]=nt[k];
} else k=nt[k];
}
}
int solve(int len,int pos) {
int i=pos,j=0,num=0;
next();
while(i<2*len) {
if(j==-1 || cs[i]==ccs[j]) {
i++;
j++;
} else {
j=nt[j];
}
if(j==len) {
// cout<<i<<endl;
if(i-len>len-1) break;
num=i-len;
j=nt[j];
}
}
return num;
}
int main() {
int t,len;
s(t);
w(t--) {
s(len);
getchar();
gets(str);
for(int i=0; i<len; i++) {
cs[i]=str[len-1-i];
}
cs[len] = '\0';
int posr = work(len,str);
int posl = work(len, cs);
int f=0,cnt=0;
for(int i=posr, j=posl; cnt<len; i++,j++,cnt++) {
if(i==len) i=0;
if(j==len) j=0;
if(str[i]>cs[j]) {
f=1;
break;
}
if(str[i]<cs[j]) {
f=2;
break;
}
}
if( f==1) printf("%d 0\n",posr+1);
else {
int top=0;
for(int i=posl; top<len ; i++) {
if(i==len) i=0;
ccs[top++] = cs[i];
}
ccs[top] = '\0';
for(int i=len; i<2*len; i++) {
cs[i]=cs[i-len];
}
cs[2*len]='\0';
int ans = solve(len,posl);
// cout<<f<<endl;
if(f==2) printf("%d 1\n",len-ans);
else if(f==0) {
if(len-ans >= posr+1)
printf("%d 0\n",posr+1);
else
printf("%d 1\n",len-ans);
}
}
}
return 0;
}
/*
5
4
abab
4
aaab
8
abcdabcd
4
abcd
4
feef
*/