zoukankan      html  css  js  c++  java
  • Seek the Name, Seek the Fame

    给定一个字符串,要求找到同时是它前缀也是后缀的字符串的个数,并且输出他们的长度。
    Input
    第一行一个数字N,第二行输入一个字符串,长度<= 10^6.
    Output
    输出这些子串的结束位置(因为它们的开始位置都是从1开始的),注意每个数字后面有一个空格.

    Sample Input
    5
    aaaaa
    Sample Output
    1 2 3 4 5

    题目大意:找出串中既是前缀又是后缀的所有子串,输出这些子串的结束位置。

    如输入:

    12

    abcabcabcabc

    输出:3 6 9 12

    sol:先求出所有next[i]的值,将next[i]--i建立一条边,构造fail树,本题是要求整个字串的前缀和后缀的个数,不难发现,每个结点都是字符串的一个前缀,根据next的定义,我们又可以得出fail树中每条链上父亲点是儿子点的后缀,所以我们跟着fail树的结点n——next(n)——...——0,这条链链找上去,就会找到我们想要的答案。

    上例next[12]=9,next[9]=6,next[6]=3,next[3]=0。这条链为:0——3(abc)——6(abcabc)——9(abcabcabc)——12(abcabcabcabc)。即前3,6,9,12位分别是该串前缀和后缀的长度。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #define maxn 1000010
     6 using namespace std;
     7 char s[maxn];
     8 int n,pre[maxn],list[maxn];
     9 int main(){
    10     scanf("%d",&n);
    11     scanf("%s",s+1);
    12     for (int i=2,j=0;i<=n;i++){
    13         while (j&&s[j+1]!=s[i]) j=pre[j];
    14         if (s[j+1]==s[i]) j++;
    15         pre[i]=j;  
    16     }
    17     for (int i=n;i;i=pre[i])//从n开始倒着记录答案 
    18        list[++list[0]]=i;
    19     for (int i=list[0];i>=1;i--) printf("%d ",list[i]);//正着输出 
    20     printf("
    ");
    21     return 0;  
    22 }
  • 相关阅读:
    How to use Log4j 2 with Spring Boot
    SpringBoot使用Redis缓存
    win10下安装redis
    mysql 8.0.15修改密码
    spring-boot集成redis实现缓存功能
    Spring Boot(三):Spring Boot 中 Redis 的使用
    关于 iView-cdn模式
    HTML5 Audio-使用 Media 事件添加进度栏
    vue-cli中自定义路径别名 assets和static文件夹的区别
    CH9001: 各浏览器对常用或者错误的 Content-Type 类型处理方式不一致
  • 原文地址:https://www.cnblogs.com/cutepota/p/12535197.html
Copyright © 2011-2022 走看看