zoukankan      html  css  js  c++  java
  • poj 2406 power strings

      题意:给一个字符串,求长度最短的循环节。

      题解:很经典的KMP的next数组的应用; 因为next数组代表模板串的最大公共前后缀,因此如果该字符串有循环节的话,那么从下标 next[len-1] 到 len-1 的这一段子串就代表了最短的循环节(不怎么明白的话可以求几个诸如abcabc、ababab 字符串的next数组出来研究下)。详见代码:

      

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <set>
     7 #include <utility>
     8 #include <vector>
     9 #include <map>
    10 #include <queue>
    11 #include <stack>
    12 const int inf=0x3f3f3f3f;
    13 const double PI=acos(-1.0);
    14 const double EPS=1e-8;
    15 using namespace std;
    16 typedef long long ll;
    17 typedef pair<int,int> P;
    18 
    19 char str[1000005];
    20 int next[1000005];
    21 void makeNext()
    22 {
    23     int q,k;
    24     int m=strlen(str);
    25     next[0]=0;
    26     k=0;
    27     for(q=1; q<m; q++)
    28     {
    29         while(k>0&&str[q]!=str[k]) k=next[k-1];
    30         if(str[k]==str[q]) k++;
    31         next[q]=k;
    32     }
    33     //for(int i=0;i<=m;i++) printf("%d ",next[i]);
    34 }
    35 bool judge(int n)
    36 {
    37     int len=strlen(str);
    38     if(len%n!=0) return false;
    39     int cnt=len/n;
    40     int t=0;
    41     while(t<len)
    42     {
    43         for(int i=0,j=t;i<cnt;i++,j++)
    44             if(str[i]!=str[j]) return false;
    45         t+=cnt;
    46     }
    47     return true;
    48 }
    49 //
    50 int main()
    51 {
    52     //freopen("test.txt","r",stdin);
    53     while(scanf("%s",str)!=EOF)
    54     {
    55         int len=strlen(str);
    56         if(len==1&&str[0]=='.') break;
    57         makeNext();
    58         //
    59         if((len-next[len-1])&&len%(len-next[len-1])==0) //len-next[len-1]得到一个循环节的长度
    60             printf("%d
    ",len/(len-next[len-1]));
    61         else 
    62             printf("1
    ");
    63         /*
    64         
    65         一开始的蠢做法=_=...
    66         int len=strlen(str);
    67         len--;
    68         int ans=1;
    69         while(next[len]) ans++,len=next[len]-1;//得出有多少个循环节
    70         if(judge(ans)) printf("%d
    ",ans); //judge()判断长度为len/ans的循环节是否可行
    71         else printf("1
    ");
    72         */
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    Razor 视图引擎的一些属性和方法
    Asp.Net Mvc Razor
    微信小程序时代已经来临
    ionic常用命令记录
    ionic中将service中异步返回的数据赋值给controller的$scope
    nodejs连接mysql实例
    转载:ionic+nodejs开发遇到的跨域和post请求数据问题
    NodeJs-- 新建项目实例
    Bootstrap学习指南
    ios开发环境配置及cordova安装与常用命令
  • 原文地址:https://www.cnblogs.com/geek1116/p/6801492.html
Copyright © 2011-2022 走看看