51Nod 1277 字符串中的最大值(KMP,裸题)

1277 字符串中的最大值

题目来源: Codility

基准时间限制:1 秒

空间限制:131072 KB 分值: 80

难度:5级算法题

一个字符串的前缀是指包含该字符第一个字母的连续子串,例如: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,是所有前缀中最大的。

Input

输入字符串S, (1 <= L <= 100000, L为字符串的长度),S中的所有字符均为小写英文字母。

Output

输出所有前缀中字符长度与出现次数的乘积的最大值。

Input示例

abababa

Output示例

10

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1277

分析:kmp裸题,之后会补上纯板子

下面给出AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=100010;
 5 char x[maxn];
 6 int kmpnext[maxn];
 7 int len;
 8 int res[maxn];///出现次数
 9 void pre_kmp(char x[],int m,int kmpnext[])
10 {
11     int i,j;
12     j=kmpnext[0]=-1;
13     i=0;
14     while(i<=m)
15     {
16         if(j==-1||x[i]==x[j])
17         {
18             kmpnext[++i]=++j;
19         }
20         else
21         {
22             j=kmpnext[j];
23         }
24     }
25     return;
26 }
27 int main()
28 {
29     cin>>x;
30     len=(int)strlen(x);
31     pre_kmp(x,len,kmpnext);
32     for(int i=len;i>=1;i--)
33     {
34         res[i]++;
35         res[kmpnext[i]]+=res[i];
36     }
37     ll ans=0;
38     for(ll i=1;i<=len;i++)
39     {
40         ans=max(ans,res[i]*i);
41     }
42     cout<<ans<<endl;
43     return 0;
44 }
时间: 2024-07-30 22:51:03

51Nod 1277 字符串中的最大值(KMP,裸题)的相关文章

51Nod 1277 字符串中的最大值 ( KMP &amp;&amp; DP )

题意 : 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd.给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值.例如:S = "abababa" 所有的前缀如下: "a", 长度与出现次数的乘积 1 * 4 = 4, "ab",长度与出现次数的乘积 2 * 3 = 6, "aba", 长度与出现次数的乘积 3 * 3 = 9, "abab&

51nod 1277 字符串中的最大值(KMP算法)

分析: KMP算法:参考http://www.cnblogs.com/c-cloud/p/3224788.html,是一个线性处理字符串匹配问题的算法 在这里利用到next数组,记t[i]为长度为i的前缀出现的次数,显然t[n]=1.next[i]即为子串[0,i]的后缀与前缀重复的最长长度,因此可以统计一下next[i]的取值的个数,然后较长的前缀出现一次代表较短的前缀也一次,递推一下即可,复杂度为O(n). 1 #include<iostream> 2 #include<cstrin

51nod 1277 字符串中的最大值

题目链接 51nod 1277 字符串中的最大值 题解 对于单串,考虑多串的fail树,发现next数组的关系形成树形结构 建出next树,对于每一个前缀,他出现的次数就是他子树的大小 代码 #include<cstdio> #include<cstring> #include<algorithm> inline int read() { int x = 0,f = 1; char c = getchar(); while(c < '0' || c > '9

hdu1686 KMP裸题

秋招快有着落啦,十一月中去北京区赛膜拜众神. 哎,好长一段时间没有刷过,重头拾起,最近得专题是字符串. Trie前一排又敲了一遍,KMP今天敲了一下. 题目一大堆废话,实际就是判断模式串出现得次数,我是对着算法导论伪代码敲得,一次AC,真得很水. /*********************************************************** > OS : Linux 3.13.0-24-generic (Mint-17) > Author : yaolong >

hdu2087(kmp裸题)

Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样.花纹条和小饰条不会超过1000个字符长.如果遇见#字符,则不再进行工作. Output 输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出

51nod 1277 KMP 前缀出现次数

51NOD 1277:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1277 跟HDU 6153还挺像的:http://www.cnblogs.com/Egoist-/p/7435573.html 相比与上面那个题,这个还要相对简单一些,只需要处理模式串自己就好了. 一开始写麻烦了,直接套了HDU6153的代码,后来发现--他就是个模式串本身的匹配,我干嘛弄那么麻烦Orz 题意:找前缀长度*出现次数的最大值,长度好说,

[2013百度软件研发笔试题] 求字符串中连续出现同样字符的最大值

题目完整描写叙述为:用递归的方式实现一个求字符串中连续出现同样字符的最大值.如aaabbcc,连续出现a的最大值为3,abbc,连续出现字符最大的值为2. 下面是我想出来的方法: #include <iostream> using namespace std; #define MAX(a, b) (a) > (b) ? (a) : (b) int Get(char *s, int n, int m)  //字符指针, 当前最长串, max最长串 {     if(*(s+1) == '\

[2013百度软件研发笔试题] 求字符串中连续出现相同字符的最大值

题目完整描述为:用递归的方式实现一个求字符串中连续出现相同字符的最大值,如aaabbcc,连续出现a的最大值为3,abbc,连续出现字符最大的值为2. 以下是我想出来的方法: #include <iostream> using namespace std; #define MAX(a, b) (a) > (b) ? (a) : (b) int Get(char *s, int n, int m)  //字符指针, 当前最长串, max最长串 {     if(*(s+1) == '\0'

数据结构与算法-字符串输出数组中的最大值

输出数组a中的最大值及其下标 #include<stdio.h> #define N 5 int main() { int a[N],i,max,t; for(i=0;i<N;i++) scanf("%d",&a[i]); max=a[0]; //把数组的第一个数赋值给max,此时对应的下标为0 t=0; for(i=1;i<N;i++) //从数组的第二个数开始判断,max是否是最大值 if(max<a[i]){ //不是最大值,就把该值赋值给m