• 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 }
  • 相关阅读:
    面向目标的场景设置--Goal-Oriented Scenario
    第二十二课 打造专业的编译环境(下)
    第二十一课 打造专业的编译环境(中)
    第二十课 打造专业的编译环境(上)
    第十九篇 路径搜索的综合示例
    第八十课 最长不下降序列
    第七十九课 最短路径(Floyd)
    第七十八课 最短路径(Dijkstra)
    第七十七课 最小生成树(Kruskal)
    第76课 最小生成树(Prim)
  • 原文地址:https://www.cnblogs.com/geek1116/p/6801492.html
Copyright © 2020-2023  润新知