zoukankan      html  css  js  c++  java
  • HDU3746 Cyclic Nacklace KMP求循环节

    HDU3746
    给定一个字符串,求:在该字符串末尾最少补充多少个字符,可以使得这个字符串获得周期性。 周期性指存在一个子串,使得该字符串可以正好分解成若干个这个子串(数量要大于1)。

    Input

    第一行是一个整数 T ( 0<T<=100 ) 代表测试数据的组数。
    之后T行每行一个字符串,由小写字母组成,字符串的长度3<=L<=100000。

    Output

    每组数据输出一行结果。

    Sample Input

    3
    AAA
    ABCA
    ABCDE

    Sample Output

    0
    2
    5

    本题有一个比较重要的性质:m-next[m] == 最小循环节长度
    #include <bits/stdc++.h>
    using namespace std;
    int T;
    int m,n;
    int nxt[100005];
    char a[100005];
    
    void getnxt(){
        int j,i;
        j = -1;
        i = 0;
        nxt[0] = -1;
        while(i < m){
            while(j != -1 && a[j] != a[i]) j = nxt[j];
            nxt[++i] = ++j;
        }
    }
    
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%s",a);
            m = strlen(a);
            getnxt();
            n = m - nxt[m];
            if (n != m && m % n == 0) puts("0");
                else printf("%d
    ",n - m%n);
        }
        return 0;
    }

    同类题目:HDU1358

    #include <bits/stdc++.h>
    using namespace std;
    int n;
    char a[1000005];
    int nxt[1000005];
    
    void getnxt(){
        int i = 0,j = -1;
        nxt[0] = -1;
        while(i < n){
            while(j != -1 && a[j] != a[i]) j = nxt[j];
            nxt[++i] = ++j;
        }
    }
    
    int main(){
        for (int t = 1;scanf("%d",&n) && n;t++){
            scanf("%s",a);
            getnxt();
            printf("Test case #%d
    ",t);
            for (int i = 1;i <= n;++i){
                int m = i - nxt[i];
                if (i % m == 0 && i != m){
                    printf("%d %d
    ",i,i/m);
                }
            }
            puts("");
        }
        return 0;
    }
    View Code

    POJ2406(注意最小循环节的长度有可能不是字符串长度的因数.....如ababa的最小循环节长度是2)

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <string>
    using namespace std;
    typedef long long ll;
    int m,n;
    int nxt[1000005];
    char a[1000005];
    
    void getnxt(){
        int j,i;
        j = -1;
        i = 0;
        nxt[0] = -1;
        while(i < m){
            while(j != -1 && a[j] != a[i]) j = nxt[j];
            nxt[++i] = ++j;
        }
    }
    
    int main(){
        while(~scanf("%s",a) && a[0] != '.'){
            m = strlen(a);
            getnxt();
            n = m - nxt[m];
            if (m % n == 0) printf("%d
    ",m/n);
                else puts("1");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java生成验证码
    SpringBoot定时任务
    事务管理
    Windows 2008 Server R2双网卡负载均衡
    HP Proliant DL580 gen9 阵列卡P440AR 高速缓存 被禁用
    Kali Debian 修改时区
    First Py From Py
    C++头文件#include<bits/stdc++.h>
    排序算法
    运算符优先级
  • 原文地址:https://www.cnblogs.com/mizersy/p/9530481.html
Copyright © 2011-2022 走看看