zoukankan      html  css  js  c++  java
  • (简单) POJ 1961 Period,扩展KMP。

    Description

    For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as AK ,that is A concatenated K times, for some string A. Of course, we also want to know the period K.

      题目就是给一个字符串,然后让对从2到N的所有前缀字符串,找出里面的重复串。

      对于找重复串的问题,用扩展KMP就可以解决。然后就是对于每个前缀,可以证明后面的前缀的最小重复串的长度一定大于等于前面的,因为形成重复串的必要条件就是i+next1[i]>=length 这样的话如果前面不符合这个式子,后面就更不用说了,必须让i增大才可能。

    代码如下:

    // ━━━━━━神兽出没━━━━━━
    //      ┏┓       ┏┓
    //     ┏┛┻━━━━━━━┛┻┓
    //     ┃           ┃
    //     ┃     ━     ┃
    //     ████━████   ┃
    //     ┃           ┃
    //     ┃    ┻      ┃
    //     ┃           ┃
    //     ┗━┓       ┏━┛
    //       ┃       ┃
    //       ┃       ┃
    //       ┃       ┗━━━┓
    //       ┃           ┣┓
    //       ┃           ┏┛
    //       ┗┓┓┏━━━━━┳┓┏┛
    //        ┃┫┫     ┃┫┫
    //        ┗┻┛     ┗┻┛
    //
    // ━━━━━━感觉萌萌哒━━━━━━
    
    // Author        : WhyWhy
    // Created Time  : 2015年07月18日 星期六 10时01分22秒
    // File Name     : 1961.cpp
    
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    
    using namespace std;
    
    const int MaxN=1000006;
    
    void EKMP_pre(int m,char s[],int next1[])
    {
        int p=0,a=1,L;
    
        next1[0]=m;
    
        while(p+1<m && s[p]==s[p+1])
            ++p;
    
        next1[1]=p;
    
        for(int k=2;k<m;++k)
        {
            L=next1[k-a];
            p=next1[a]+a-(next1[a]!=0);
    
            if(k+L-1<p)
                next1[k]=L;
            else
            {
                ++p;
    
                while(p<m && s[p]==s[p-k])
                    ++p;
    
                next1[k]=p-k;
                a=k;
            }
        }
    
        next1[m]=0;
    }
    
    int next1[MaxN];
    char s[MaxN];
    int N;
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        
        int cas=1;
        int minn;
    
        while(~scanf("%d",&N) && N)
        {
            minn=1;
            scanf("%s",s);
    
            EKMP_pre(N,s,next1);
    
            printf("Test case #%d
    ",cas++);
    
            for(int i=1;i<N;++i)
            {
                while(minn<=i && next1[minn]+minn<i+1)
                    ++minn;
    
                if(minn<=i && (i-minn+1)%minn==0)
                    printf("%d %d
    ",i+1,(i-minn+1)/minn+1);
            }
    
            puts("");
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    程序员通过什么渠道接外包项目
    中小型软件项目开发一般流程建议
    DevExpress GridControl功能总结
    页面UI注意事项,你在乎吗?
    加密,解密
    本地化(国际化)
    AutoLayout(自动布局)
    UItableView与UICollectionView
    分享iOS开发常用(三方类库,工具,高仿APP,实用网站,技术干货)
    NSPredicate
  • 原文地址:https://www.cnblogs.com/whywhy/p/4656396.html
Copyright © 2011-2022 走看看