TB椰程 TypeBuddy 打字搭子

Power Strings

一本通·提高篇 · 代码 · cpp · 难度 3/5 · 共 761 字

KMP前缀函数求最小循环节重复次数

  • 一本通
  • 例

正文

// 原题:https://oj.yecheng.tv/p/T1466
// 题意:每行一个字母串,遇到单独一个半角句号 "." 结束,输出该串最多由多少个相同子串重复连接而成。
// 思路:求前缀函数 nxt,最小循环节长度为 n-nxt[n],若 n 能被它整除则答案为 n/(n-nxt[n]),否则只能是 1。
// 复杂度:O(单串长度) 时间 / O(单串长度) 空间
// 易错点:只有整行恰好是 "." 才终止;必须用整除判断,否则 abababa 这类不满整周期的串会输出错误倍数。
#include <bits/stdc++.h>
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    string s;
    while(cin>>s){
        if(s==".") break;
        int n=(int)s.size();
        vector<int> nxt(n+1,0);
        for(int i=1;i<n;i++){
            int j=nxt[i];
            while(j>0&&s[i]!=s[j]) j=nxt[j];
            if(s[i]==s[j]) j++;
            nxt[i+1]=j;
        }
        int p=n-nxt[n];
        if(n%p==0) cout<<n/p<<'\n';
        else cout<<1<<'\n';
    }
    return 0;
}

一本通·提高篇的其它内容

打字首页 · 词库画廊 · 编程打字 · 指法入门 · 天梯榜 · 数据分析 · 班级课堂 · 关于我们
椰程 TypeBuddy 打字搭子 —— 键盘指法练习 · 单词记忆 · 班级课堂 · 在线 PK