• 2018牛客暑假多校三 E(KMP运用)


    题目描述:

        给你一个字符串S,你要对字符串S的每一位i将前i位的字符串移动到尾部形成一个新的字符串,如果形成的字符串相同则归为一类Li。现在让你将Li类按照字典序排序,并让你输出每一类的数量和每一类中字符串对应的下标i。

    题目分析:

        观察可以发现,将字符串移动形成新的字符串,当且仅当字符串中存在循环节时,才会出现新构成的字符串相同。因此这个问题就转化成求一个字符串的循环节的问题。

        至此,这个问题就可以用kmp中的next数组进行计算。(有一个重要结论,如果对于一个长度为L的字符串,如果L%(L-next[L])==0则代表它具有循环节,且循环节的长度为L-next[L])

    代码:

    #include <bits/stdc++.h>
    #define maxn 1000005
    using namespace std;
    int nex[maxn];
    char str[maxn];
    void get_next(char *s){//获取next数组
        int i,j;
        j=nex[0]=-1;
        i=0;
        int len=strlen(s);
        while(i<len){
            while(j!=-1&&s[i]!=s[j]) j=nex[j];
            nex[++i]=++j;
        }
    }
    int main()
    {
        scanf("%s",str);
        get_next(str);
        int len=strlen(str);
        int tmp=len-nex[len];
        if(len%tmp!=0){//如果没有循环节,则每个都类都为1
            cout<<len<<endl;
            for(int i=0;i<len;i++){
                printf("1 %d
    ",i);
            }
        }
        else{
            cout<<tmp<<endl;//字符串的种类的数目为循环节的长度
            for(int i=0;i<tmp;i++){
                cout<<len/tmp;//每个字符串种类的个数
                for(int j=i;j<len;j+=tmp){
                    cout<<" "<<j;
                }
                puts("");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    目标检测网络CenterNet详解(四)
    样本不均衡问题
    目标检测网络Faster RCNN详解(一)
    SpringCloud学习总结(八)——服务调用Feign
    OpenFeign(2020-10-13)
    Feign真正正确的使用方法
    微服务实战SpringCloud之Feign简介及使用
    spring cloud gateway网关和负载均衡框架ribbon实战
    Studio 3T 破解
    JVM 垃圾回收?全面详细安排!
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007256.html
Copyright © 2020-2023  润新知