码迷,mamicode.com
首页 > 其他好文 > 详细

UESTC_全都是秋实大哥 2015 UESTC Training for Search Algorithm & String<Problem J>

时间:2015-05-13 06:07:42      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

J - 全都是秋实大哥

Time Limit: 5000/2000MS (Java/Others)     Memory Limit: 32000/32000KB (Java/Others)
 

秋实大哥是一个多愁善感的人,偶尔也会唱唱两句伤情的歌。每次唱完后,秋实大哥都能解决一道问题!这次也不例外。

秋实大哥告诉了你 一些关于这个问题的信息

如果一个字符串S是由若干个子串a连续拼接而成的,则称aS的循环节,即A=a+a+...+a。比如 aba 是 abaabaaba 的循环节。
一个字符串可能存在多个循环节,比如 aaaaaaaa ,含有4个循环节,分别是 a , aa , aaaa , aaaaaaaa 。很显然,一个字符串是其本身的循环节。在这4个循环节中,长度最小的是"a",所以"a"是S的最小循环节。
字符串所有循环节里长度最小的循环节,就是该字符串的最小循环节。
一个长度为N的字符串,含有N个非空前缀。定义P(i)表示S的第i个非空前缀(0i<|S|)P(i)=S012...i。比如"abcde"含有5个非空前缀,分别是"a",“ab”,“abc”,“abcd”,“abcde”。

现给一个字符串S,请先按顺序输出S的每一个非空前缀的最小循环节的长度,然后,再输出S的最小循环节。

秋实大哥唱完了,问题也解决了,现在他请你来解决这个问题。

Input

第一行输入一个字符串S0<|S|3106),S只含有小写英文字母(a-z)

Output

第一行输出 |S| 个数,分别表示S的每一个非空前缀的最小循环节的长度,每两个数用一个空格隔开,最后一个数后面不要有空格。

第二行输出一个字符串,表示S的最小循环节。

Sample input and output

Sample InputSample Output
ab
1 2
ab
aaaaaaaaa
1 1 1 1 1 1 1 1 1
a
aaaaaaaad
1 1 1 1 1 1 1 1 9
aaaaaaaad
abbaaddaabbaadda
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 8
abbaadda
abbaabbaabbaabba
1 2 3 4 5 6 7 4 9 10 11 4 13 14 15 4
abba

 

解题报告:

这是一道求最小循环节题目

 关键在于了解next数组的含义,next[i] 表示 0 - i-1的最大前缀后缀最大值,我们先假设它是循环的,那么显然满足i % (i - next[i]) == 0 , ( 长度是整数倍 ),之后next[i] != 0 (若为 0 ,此时前缀后缀的长度最大值0,也就是说,就是本身)

 

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;
const int maxn = 3e6 + 500;
char s[maxn];
int len,front[maxn];

void build_front()
{
   front[0] = -1;
   int t1 = -1,t2 = 0;
   while(t2 < len)
    {
        if (t1 == -1 || s[t1] == s[t2])
         front[++t2] = ++ t1;
        else
         t1 = front[t1];
    }
}

int main(int argc,char *argv[])
{
  scanf("%s",s);
  len = strlen(s);
  build_front();
  printf("1");
  for(int i = 2 ; i <= len ; ++ i)
   if (i % (i-front[i]) == 0 && front[i] != 0 )
    printf(" %d",i-front[i]);
   else
    printf(" %d",i);
  printf("\n");
  if (len % (len-front[len]) == 0 && front[len] != 0)
   {
         int cot = len - front[len];
         for(int i = 0 ; i < cot ; ++ i)
          printf("%c",s[i]);
   }
  else
   printf("%s",s);
  printf("\n");
  return 0;
}

 

UESTC_全都是秋实大哥 2015 UESTC Training for Search Algorithm & String<Problem J>

标签:

原文地址:http://www.cnblogs.com/Xiper/p/4499176.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!