51nod1277 字符串中的最大值【KMP】

一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd。给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值。

例如:S = “abababa” 所有的前缀如下:

“a”, 长度与出现次数的乘积 1 * 4 = 4,
“ab”,长度与出现次数的乘积 2 * 3 = 6,
“aba”, 长度与出现次数的乘积 3 * 3 = 9,
“abab”, 长度与出现次数的乘积 4 * 2 = 8,
“ababa”, 长度与出现次数的乘积 5 * 2 = 10,
“ababab”, 长度与出现次数的乘积 6 * 1 = 6,
“abababa”, 长度与出现次数的乘积 7 * 1 = 7.

其中"ababa"出现了2次,二者的乘积为10,是所有前缀中最大的。

正解思路:
通过求next数组 和 递归next数组的方法记录字符串出现的次数。
代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
#define N 100005
using namespace std;
typedef long long ll;
int f[N],cnt[N];
char str[N];
int len;

void getnext(){

    f[0]=0,f[1]=0;
    for(int i=1;i<len;i++){
       int j=f[i];
        while(j&&str[i]!=str[j])j=f[j];
        f[i+1]=(str[i]==str[j]?j+1:0);
    }


}
int main(){
    cin>>str;
    len=strlen(str);
    getnext();

    for(int i=len;i>=1;i--){
        cnt[i]++;
        cnt[f[i]]+=cnt[i];
    }
    ll res=0;

    for(ll i=1;i<=len;i++){
        res= max(i*cnt[i],res);
    }

    cout<<res<<endl;

}


发布了156 篇原创文章 · 获赞 9 · 访问量 6540

猜你喜欢

转载自blog.csdn.net/weixin_43438700/article/details/102596767