• E


    题目大意:

         多组。给一个n,输入长度为n 的串,求:这个串所有存在循环节的前缀,输出前缀长度和循环次数(不重叠)。

    解题思路:

        从i=0开始,判断前缀是不是存在循环节,即(i+1)%(i-next[i]) 是否==0 。注:next[i]值是0或-1的忽略,说明前面不存在任何循环节。(关于循环节解释的见《KMP 专题知识》)。

    参考代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 using namespace std;
     4 char a[1000010];
     5 int next[1000010];
     6 int n;
     7 void GetNext()    //获得a数列的next数组
     8 {
     9     int i=0,k=-1;
    10     next[0] = -1;
    11     while(i<n){
    12         if(k==-1){
    13             next[i+1] = 0;
    14             i++;k++;
    15         }
    16         else if(a[i]==a[k]){
    17             next[i+1] = k+1;
    18             i++;k++;
    19         }
    20         else
    21             k = next[k];
    22     }
    23 }
    24 void DisRes(int num)
    25 {
    26     int j;
    27     printf("Test case #%d
    ",num);
    28     for(int i=0;i<=n;i++)
    29     {
    30         if(next[i]==-1 || next[i]==0)   //next[i]是-1或0的忽略,说明之前没有周期性前缀
    31             continue;
    32         j = i - next[i];
    33         if(i%j==0)  //能整除,说明存在周期性前缀
    34             printf("%d %d
    ",i,i/j);    //输出这个前缀的长度和周期数
    35     }
    36     printf("
    ");
    37 }
    38 int main()
    39 {
    40     int num = 0;
    41     while(scanf("%d",&n)!=EOF)
    42    {
    43         if(n==0) break;
    44         scanf("%s",a);
    45         GetNext();  //获得next[]数组
    46         DisRes(++num);  //输出结果
    47     }
    48     return 0;
    49 }
    这个回头自己写过

        

    まだまだだね
  • 相关阅读:
    Ubuntu安装vmtools后,Window无法向其复制文件
    Tomcat弱密码导致getshell
    免杀工具 FourEye
    ubuntu 安装docker
    做有追求的程序员
    nrm 源切换工具 Jim
    url加载图片,如何判断加载成功 Jim
    vue实现文件流预览pdf Jim
    将日期格式转换成时间戳 Jim
    js如何实现多线程之web worker Jim
  • 原文地址:https://www.cnblogs.com/xxQ-1999/p/7522744.html
Copyright © 2020-2023  润新知