• hdu-1358(kmp)


    题意:给你一个长度为n的字符串,问你一共有多少Xi——从0开始到Xi的这段长度这个字符子串是循环串,并输出最多的循环节的次数;

    解题思路:用kmp的next数组,我们从next数组的值中可以看出这个字串是否为循环串,例如:

    void get_next()
    {
        int j,k;
        j=0;k=-1;next1[0]=-1;
        while(j<tlen)
        {
            if(k==-1||t[j]==t[k])
                next1[++j]=++k;
            else
                k=next1[k];
        }
    }
    

      

    ababa

    next【0】=-1,next【1】=0,next【2】=0,next【3】=1,next【4】=2;next【5】=3;

    从next数组中可以看出,如果一个字串是循环的,那么对应的next【i+1】(这里的next数组是除去本身的最大前后缀,所以退后一位)*2一定是>=当前字串长度的;不然,就没有循环节覆盖整个字符子串,但这只是前提,从例子中next【5】=3也满足,但长度为5的字串并不是循环节,所以再加入条件:

    if(next1[i]*2>=i)
                {
                    if(i%(i-next1[i])==0)
    
                    {
                        ans[++cot][1]=i;
                        ans[cot][2]=i/(i-next1[i]);
                    }
                }
    

      这个条件是判定这个字串是否正好被循环节完全覆盖;这样在记录一下满足的位置就行了;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<math.h>
    #include<cstdlib>
    using namespace std;
    char t[1005000];
    int next1[1005000];
    int tlen;
     int ans[1005000][3];
    void get_next()
    {
        int j,k;
        j=0;k=-1;next1[0]=-1;
        while(j<tlen)
        {
            if(k==-1||t[j]==t[k])
                next1[++j]=++k;
            else
                k=next1[k];
        }
    }
    int main()
    {
        int tt=0;
    
        while(scanf("%d",&tlen)!=EOF)
        {
            if(tlen==0)
                return 0;
            tt++;
            scanf("%s",t);
            get_next();
            int cot=0;
            for(int i=0;i<=tlen;i++)
            {
                if(next1[i]*2>=i)
                {
                    if(i%(i-next1[i])==0)
    
                    {
                        ans[++cot][1]=i;
                        ans[cot][2]=i/(i-next1[i]);
                    }
                }
            }
            printf("Test case #%d
    ",tt);
            for(int i=1;i<=cot;i++)
                printf("%d %d
    ",ans[i][1],ans[i][2]);cout<<endl;
    }
        }
    

      

  • 相关阅读:
    移动 App 接入 QQ 登录/分享 图文教程
    Word 最后一页无法删除-解决办法
    Java快速入门-04-Java.util包简单总结
    Java快速入门-03-小知识汇总篇(全)
    SSM 框架-06-详细整合教程(IDEA版)(Spring+SpringMVC+MyBatis)
    二叉树的镜像
    浅析I/O模型及其设计模式
    远程方法调用(RMI)原理与示例
    树的子结构
    合并两个排序的链表
  • 原文地址:https://www.cnblogs.com/huangdao/p/9284457.html
Copyright © 2020-2023  润新知