您的位置:首页 > 其它

hdu3374-最小表示法&&kmp求循环节-String Problem

2017-08-23 19:28 357 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3374

之前做过一道exkmp的题,就是先求的 循环节。就是用的这个代码的方法。。

开始先用表示法来算的,然后暴力枚举超时了,就想到用循环节式一下。

用string会超时,挂载也超时

给你一个串,分别输出

字典序最小同构串的 第一个字符位置(从1开始)

出现次数

字典序最大同构串的第一个位置

出现次数

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+1000;
int MAXR(char  s[]){
int len=strlen(s)/2;
int i=0;int j=1;int k=0;
while(i<len&&j<len){
k=0;
while(s[i+k]==s[j+k]&&k<len)k++;
if(k==len) return min(i,j);
if(s[i+k]<s[j+k]) i=max(i+k+1,j+1);
else if(s[i+k]>s[j+k]) j=max(j+k+1,i+1);
}
return min(i,j);
}
int MINR(char s[]){
//cout<<s<<"!!"<<endl;
int len=strlen(s)/2;
// cout<<len<<endl;
int i=0;int j=1;//int k=0;
while(i<len&&j<len){
int k=0;
while(s[i+k]==s[j+k]&&k<len)k++;
if(k==len) return min(i,j);
if(s[i+k]>s[j+k])
i=max(i+k+1,j+1);
else if(s[i+k]<s[j+k])
j=max(j+k+1,i+1);
}
return min(i,j);
}
int nex[maxn];
int getnext(int len,char s[]){
nex[0]=-1;
int i=0;int k=-1;
while(i<len){
if(k==-1||s[i]==s[k]){
nex[++i]=++k;
}
else
k=nex[k];

4000
}
}
int main()
{   //ios::sync_with_stdio(false);
char  s[maxn];
while(~scanf("%s",s)){
int len=strlen(s);
getnext(len,s);
int siz=len-nex[len];//计算 循环节
int kk=0;
if(!(len%siz))
kk=len/siz;
else
kk=1;
for(int i=0;i<len;i++){
s[i+len]=s[i];
}
int max1=MAXR(s);
int min1=MINR(s);
int flag1=0;
int flag2=0;
printf("%d %d %d %d\n",min1+1,kk,max1+1,kk);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  string