zoukankan      html  css  js  c++  java
  • Poj 1961 Period

    题面

    http://poj.org/problem?id=1961

    题解

    发现一个性质 一个循环的串 假设循环节长度为L 那么我们取其前size-L位,后size-L位,这两个串相同

    相对应的,如果一个长度为size的串,我们取前k位,和后k位相同 那么size-k一定是这个串的循环节

    所以我们只要对于每一位 找到前i位的子串的最长的前缀与对应长度的后缀相同的长度 那么i-length一定是答案

    最长前缀=后缀 我们不难想到kmp的next数组

    所以做一下kmp 求得next数组就做完了

    复杂度$O(n)$

    Code

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 using namespace std;
     5 typedef long long ll;
     6 
     7 ll read(){
     8     ll x=0,f=1;char c=getchar();
     9     while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
    10     while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
    11     return x*f;
    12 }
    13 
    14 int n;
    15 char s[1000100];
    16 int nxt[1000100];
    17 
    18 int main(){
    19 #ifdef LZT
    20     freopen("in","r",stdin);
    21 #endif
    22     int tc=0;
    23     while(1){
    24         n=read();
    25         if(!n) break;
    26         scanf("%s",&s);
    27         nxt[0]=0,nxt[1]=0;
    28         for(int i=1;i<n;i++){
    29             int j=nxt[i];
    30             while(j && s[i]!=s[j]) j=nxt[j];
    31             nxt[i+1]=(s[i]==s[j])?j+1:0;
    32         }
    33         printf("Test case #%d
    ",++tc);
    34         for(int i=1;i<=n;i++){
    35             if(i%(i-nxt[i])==0 && nxt[i]){
    36                 printf("%d %d
    ",i,i/(i-nxt[i]));
    37             }
    38         }
    39         puts("");
    40     }
    41     return 0;
    42 }

    Review

    动机?

    kmp的一个功能就是处理循环串

    这算是个模板题?

  • 相关阅读:
    特别实用的 6 款 Python 特殊文本格式处理库推荐
    小白版Python环境搭建,还不会你就掐死小编吧(建议收藏)
    Python抓取网页数据的终极办法
    Neo4j CQL -(17)- NULL值
    Neo4j CQL -(16)- 合并
    Neo4j CQL -(15)- LIMIT和SKIP子句
    Neo4j CQL -(14) -UNION联合
    Neo4j CQL
    Neo4j CQL
    Neo4j CQL
  • 原文地址:https://www.cnblogs.com/wawawa8/p/9403392.html
Copyright © 2011-2022 走看看