zoukankan      html  css  js  c++  java
  • 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;
    }
        }
    

      

  • 相关阅读:
    深入揭秘HTTPS安全问题&连接建立全过程
    申请https证书需要注意的4大问题
    如何排查APP服务端和客户端是否支持ATS
    Apache和Nginx配置支持苹果ATS方法
    服务器配置ssl证书支持苹果ATS方法
    HTTPS背后的加密算法
    图解HTTPS协议加密解密全过程
    Java单例模式——并非看起来那么简单
    flask+mako+peewee(上)
    [转]ubuntu中查找软件的安装位置
  • 原文地址:https://www.cnblogs.com/huangdao/p/9284457.html
Copyright © 2011-2022 走看看