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

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];
    }
}
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值