zoukankan      html  css  js  c++  java
  • hdu 1358 Period KMP

    题目大意:对于一个字符串,找由循环字符串组成的位置,并输出最多循环了几次,比如两个样例,第一个是 aaa ,所以在第二个位置由子串a循环两次得到,第三个位置由a循环3次,第二个样例aabaabaabaab,在第二个位置由a循环两次,在第六个位置由aab循环两次,在第9个位置由aab循环3次,在第12个位置由aab循环4次,注意,在第12个位置不是由aabaab循环2次,因为要求循环次数最多。

    kmp可以解决循环子串问题,kmp中首先预处理出来一个p数组,p[ i ]=a表示前a个字符等于后a个字符,仔细想一下,前面a个字符往后平移i-a字符后与后面a个字符重合,令i - a = L,所以a[ 1 ] = a[ 1+ L],因为a[ 1+ L]也往后平移了,所以a[ 1+ L] = a[ 1+ 2*L]=a[ 1+ 3*L]=......,所以说如果a[ i ] 是循环子串的话i必须能整除L,循环次数为i/L,画个图会帮助理解~~

    #include <stdio.h>
    char a[1000020];
    int p[1000020];
    int main()
    {
    	int n,i,j,tot=1;
        while(1)
        {
    		scanf("%d",&n);
    		if(n==0) break;
    		getchar();
    		for(i=1;i<=n;i++) scanf("%c",&a[i]);
            j=0;
            p[1]=0;
            for(i=2;i<=n;i++)
            {
                while(j>0&&a[i]!=a[j+1]) j=p[j];
                if(a[i]==a[j+1])
                    j++;
                p[i]=j;
            }
    		printf("Test case #%d
    ",tot);
            for(i=1;i<=n;i++)
    			if(p[i]!=0&&i%(i-p[i])==0)
    				printf("%d %d
    ",i,i/(i-p[i]));
    		printf("
    ");
    		tot++;
        }
        return 0;
    }
    


     

  • 相关阅读:
    架构漫谈1
    如何将本地工程上传到github
    寒假日报day23
    寒假日报----首都之窗爬虫大作业
    寒假日报day22
    寒假日报day21
    关于webmagic的post请求
    寒假日报day20
    寒假日报day19
    吾日三省吾身(41)
  • 原文地址:https://www.cnblogs.com/vermouth/p/3710194.html
Copyright © 2011-2022 走看看