• hdu P3374 String Problem


    今天又在lyk大佬的博客学会了——最小表示法(异常激动
    发篇题解纪念一下
    说在前面:给luogu提个建议最小表示法的题太少了,都被hdu抢去了!!!



    我们先看一下题目

    看完后可以用一个字概括——,两个字——懵逼

    在这里我提供题目大意:

    输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数。

    由于本人懒于写字符串最小表示法,那么我们就来借鉴一下lykkk优秀总结

    看完之后,显然我们就明白了许多

    因为题目中让我们同时求出最大和最小的起始位置

    所以我们不仅要来一遍最小表示法,还要来一遍最大表示法

    其实这两种算法唯一的区别就是:

    最小表示法中当str[i+k]>str[j+k]时,i+k的字典序比j+k的字典序大,那么我们就要抛弃当前以i为头的字符串,往后走即i+=k+1

    最大表示法就是当str[i+k]<str[j+k]时,我们才要更新起点

    各来一遍后,题目就完成了一半

    至于KMP在这里的作用就是,利用next数组来求循环节,则次数=长度/循环节长度

    说到这里,显然三个子函数足以解决这个问题了

    我们最后只需要在主函数里根据题意输入输出即可

    无代码,不成方圆

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1100000;
    int n;
    char s[N];
    int nxt[N];
    void Kmp(int l){//用来求最小循环节的个数
        int j=0,k=nxt[0]=-1;
        while(j<l){
            if(k==-1 || s[j]==s[k]) nxt[++j]=++k;
            else k=nxt[k];
        }
    }
    int Min(char s[],int l){
        int i=0,j=1,k=0;
        while(i<l && j<l && k<l){
            if(s[(i+k)%l]==s[(j+k)%l]) k++;
            else if(s[(i+k)%l]>s[(j+k)%l]) i+=k+1,k=0;
            else j+=k+1,k=0;
            if(i==j) i++;
        }
        return min(i,j);
    }
    int Max(char s[],int n){
        int i=0,j=1,k=0;
        while(i<n && j<n && k<n){
            if(s[(i+k)%n]==s[(j+k)%n]) k++;
            else if(s[(i+k)%n]<s[(j+k)%n]) i+=k+1,k=0;//唯一的区别
            else j+=k+1,k=0;
            if(i==j) i++;
        }
        return min(i,j);
    }
    int main(){//常规操作
        while(scanf("%s",s)!=EOF){
            int len=strlen(s);
            Kmp(len);
            int maxn=Max(s,len),minn=Min(s,len);
            printf("%d %d %d %d
    ",minn+1,len/(len-nxt[len]),maxn+1,len/(len-nxt[len]));
        }
        return 0;
    }

    完结,撒花!

  • 相关阅读:
    一个python实现重试机制的简要实践
    元编程技术和动态编译
    NDoc使用简要手册增加了例子代码
    问dudu,评论是否只能删除,不可以直接修改?
    《C#类设计手册》读书随笔(4)
    .NET下几种动态生成代码方式比较
    NDoc使用简要手册
    "引用"表示什么?
    .NET环境编程全景不错的书
    C#实现动态灵活调用业务方法的机制
  • 原文地址:https://www.cnblogs.com/xmex/p/10505906.html
Copyright © 2020-2023  润新知