hdu 1358 Period

点击打开链接hdu 1358


思路:kmp+最小循环节

分析:
1 题目要求的是给定一个长度为n的字符串,求出字符串的所有前缀字符串中该字符串刚好由k个最小循环节够成,由于题目要求k最大那么就是这个循环节最小
2 只要先求出next数组,然后去枚举所有的前缀找到满足的输出长度和k

代码:

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

#define MAXN 1000010

int n;
int next[MAXN];
char pattern[MAXN];

void getNext(char *str){
   int m = strlen(str);
   next[0] = next[1] = 0;
   for(int i = 1 ; i < m ; i++){
      int j = next[i];
      while(j && str[i] != str[j])
         j = next[j];
      next[i+1] = str[i] == str[j] ? j+1 : 0;
   }
}

int main(){
   int Case = 1;
   while(scanf("%d%*c" , &n) && n){
      scanf("%s" , pattern);
      getNext(pattern);
      printf("Test case #%d\n" , Case++);
      for(int i = 2 ; i <= n ; i++){
         int len = i;
         int cir = len-next[len];
         if(cir == 1)/*如果最小循环节为1那么肯定是满足的*/
           printf("%d %d\n" , len , len);
         else if(cir != len && len%cir == 0)/*这里注意一下是cir != len*/
           printf("%d %d\n" , len , len/cir);
         else
           continue;
      }
      printf("\n");
   }
   return 0;
}



你可能感兴趣的:(hdu 1358 Period)