Codeforces Round #506 (Div. 3) A Many Equal Substrings

地址:http://codeforces.com/contest/1029/problem/A

KMP算法求字符串的最小循环节
KMP最小循环节、循环周期:
定理:假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0…len-next[len]-1]。
(1)如果len可以被len - next[len]整除,则表明字符串S可以完全由循环节循环组成,循环周期T=len/L。
(2)如果不能,说明还需要再添加几个字母才能补全。需要补的个数是循环个数L-len%L=L-(len-L)%L=L-next[len]%L,L=len-next[len]。

算法理解:https://blog.csdn.net/hao_zong_yin/article/details/77455285

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 2 * 1e5 + 5;

#define fi first
#define se second

int nextnum[500];

int main()

{
    string s;
    int step=1,n,k;
    cin >> n >> k;
    cin >> s;
    if(k == 1){
        cout << s << endl;
        return 0;
    }
    int len=s.size();
    memset(nextnum,0,sizeof(0));
    int i=0,j=1;
    while(j<len)  //先写出next数组
    {
        if(s[i]!=s[j]&&i!=0)
        {
            i=nextnum[i-1];
        }
        else if(s[i]!=s[j]&&i==0)
        {
            nextnum[j]=0;
            j++;
        }
        else if(s[i]==s[j])
        {
            nextnum[j]=i+1;
            j++,i++;
        }
    }
    int l = len - nextnum[len-1];
    string x = s.substr(0,l);
    //cout << x << endl;
    int num = (len + l - 1) / l;
    //cout << num << endl;
    //处理开头
    for(int i = 0;i < num;++i)
    {
        cout << x;
    }
    for(int i = 1;i < k - 1;++i)
    {
        cout << x;
    }
    //处理结尾
    if(len % l == 0){
        //循环节长度为len
        cout << x;
    }else{
        int ans = l - len % l;
        //cout << ans << endl;
        for(int i = 0;i < x.size() - ans;++i)
            cout << x[i];
    }
    cout << endl;
    return 0;

}

猜你喜欢

转载自blog.csdn.net/qq_36386435/article/details/82262202