• FZU 1901 Period II(KMP循环节+公共前后缀)


    题目链接:http://acm.fzu.edu.cn/problem.php?pid=1901

    题目大意:题目大意求出所有p满足s[i]=s[i+p](i<=len-p)

    解题思路:

    其实就是要找出所有的循环节(不只是最小的),
    循环节本质跟公共前后缀有关,可以通过递归的方法求出所有公共前后缀ti,那么len-ti就是相应循环节。

    之前写的计算最小循环节,累加循环节得到前缀的方法是有问题的,过不了下面这种数据。
    数据:abacaba
    结果应该是4,6,7
    而求出来的是4,7。因为忽略了除了最小循环节外的其他循环节。

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=1e6+5;
     7 
     8 int len;
     9 int nxt[N],ans[N];
    10 char p[N];
    11 
    12 void getnext(){
    13     int i=0,j=nxt[0]=-1;
    14     while(i<len){
    15         while(j!=-1&&p[i]!=p[j])
    16             j=nxt[j];
    17         nxt[++i]=++j;
    18     }
    19 }
    20 
    21 int main(){
    22     int t,cas=0;
    23     scanf("%d",&t);
    24     while(t--){
    25         scanf("%s",p);
    26         len=strlen(p);
    27         getnext();
    28         int t=nxt[len];
    29         int cnt=0;
    30         while(t!=-1){
    31             if(t>=0) ans[cnt++]=len-t;
    32             t=nxt[t];
    33         }
    34         printf("Case #%d: %d
    ",++cas,cnt);
    35         for(int i=0;i<cnt;i++){
    36             printf("%d%c",ans[i],i==cnt-1?'
    ':' ');
    37         }
    38     }
    39     return 0;
    40 }
  • 相关阅读:
    实习日记7.28
    实习日记7.27
    实习总结(第三周)
    实习日记7.26
    实习日记7.25
    实习总结(第二周)
    实习总结(第一周)
    实习日记7.22
    实习日记7.21
    5月4下
  • 原文地址:https://www.cnblogs.com/fu3638/p/8491208.html
Copyright © 2020-2023  润新知