首页 > 其他 > 详细

Seek the Name, Seek the Fame

时间:2020-03-20 22:22:46      阅读:64      评论:0      收藏:0      [点我收藏+]

给定一个字符串,要求找到同时是它前缀也是后缀的字符串的个数,并且输出他们的长度。
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树,本题是要求整个字串的前缀和后缀的个数,即为完全覆盖,所以我们只需要构造[0,...,next[len],len]的这条链就可以了.

上例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("\n");
21     return 0;  
22 }

 

Seek the Name, Seek the Fame

原文:https://www.cnblogs.com/cutepota/p/12535197.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!