题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4763

题意:给出一个字符串,问能不能在该串的前中后部找到相同的子串,输出最长的字串的长度。

分析:kmp的next[]数组应用。

next[i]=k表示在位置i之前有k个字符与字符串前k个字符相同,利用这个性质,先求出next[]数组,注意next[len]也要求出来,next[i]就表示字符串的后部与前部相同的长度,这样就只需找有没有中部就可以了。在next[i]到len-next[i]之间找有没有和next[i]相同的值就行了,找到就表示有中部,否则没有,这时i=next[i],然后继续找有没有中部,一直到next[i]==0为止。

之前的做法是错的,因为题目要求前缀,中缀,后缀不能出现重叠,之前的做法会导致3个错误:

1.可能会导致求出来的前缀和中缀重叠导致错误;

2.在next[i]到len-next[i]中间可能出现长度与前缀相同但是字符不一样的字串,比如:aaaaabbbbaaaa,这样用之前的做法会得出错误的答案;

3.如果前缀和中缀是连续的,那么next[len]就有可能是前缀和中缀的总长度和了,这样也会错误。

所以不能仅仅依靠next[]数组来求解

正确的做法是:

在next[i]到len-next[i]之间用kmp匹配前缀,如果匹配成功,则说明能找到中部,否则不能,i=next[i]然后继续查找中部,直到next[i]==0即可.

根据next[]数组的性质,循环的次数不超过3次,因为如果后部和前部不相同的话,next[i]==0,这样很快就可以跳出循环了。

还可以加个优化:前中后部字串的长度最多为len/3,如果next[i]>len/3的话就可以直接跳过查找中部,进入下一次循环了。但是优化不大,因为循环次数非常少。

AC代码:

 #include<cstdio>
#include<cstring>
const int N=+;
int next[N];
char s[N],c[N],d[N];
void get_next(char s[])
{
int len=strlen(s);
int i=;
int j=-;
next[]=-;
while(i<=len) //注意要==
{
if(j==-||s[i]==s[j])
{
i++;
j++;
next[i]=j;
}
else
j=next[j];
}
}
int kmp(char t[],char s[])
{
int i,j,k,m,n;
m=strlen(s);
n=strlen(t);
i=j=k=;
while(i<m&&j<n)
{
if(j==- || t[j]==s[i])
{
i++;
j++;
}
else
j=next[j];
}
if(j>=n)
return ;
else
return ;
}
int main()
{
int t,j,k;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
get_next(s);
int len=strlen(s);
int i=next[len];
int flag=;
while(i>)
{
while(i>len/)
i=next[i];
if(i<=)
break;
/********************************
错误解法:
for(j=i;j<=len-i;j++) //找中部
if(next[j]==i)
{
flag=1;
break;
}
********************************/
for(k=,j=;j<i;j++)
c[k++]=s[j];
c[k]='\0';
for(k=;j<len-i;j++)
d[k++]=s[j];
d[k]='\0';
flag=kmp(c,d);
if(flag==) //找到了
break;
else
i=next[i]; //找不到,循环继续
}
if(flag)
printf("%d\n",i);
else
printf("0\n");
}
return ;
}

2013长春网赛1005 hdu 4763 Theme Section(kmp应用)的更多相关文章

  1. hdu 4763 Theme Section(KMP水题)

    Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  2. HDU 4763 Theme Section(KMP灵活应用)

    Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  3. 2013长春网赛1009 hdu 4767 Bell(矩阵快速幂+中国剩余定理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4767 题意:求集合{1, 2, 3, ..., n}有多少种划分情况bell[n],最后结果bell[ ...

  4. 2013长春网赛1001 hdu 4759 Poker Shuffle

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4759 题意:有一堆2^n的牌,牌原先按(1,2,....k)排序,每一次洗牌都将牌分成两种情况:(1, ...

  5. 2013长春网赛1004 hdu 4762 Cut the Cake

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4762 题意:有个蛋糕,切成m块,将n个草莓放在上面,问所有的草莓放在同一块蛋糕上面的概率是多少.2 & ...

  6. 2013长春网赛1010 hdu 4768 Flyer

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4768 题意:有n个社团发传单,每个社团发给编号为A_i, A_i+C_i,A_i+2*C_i,…A_i ...

  7. 2013长春网赛 1006 hdu 4764 Stone(巴什博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4764 题意:Tang 和 Jiang 玩一个游戏,轮流写下一个数,Tang先手,第一次Tang只能写[ ...

  8. HDU 4763 Theme Section(KMP+枚举公共前后缀)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4763 题目大意: 给你一个字符串s,存在一个子串E同时出现在前缀.中间.后缀,即EAEBE这种模式,A ...

  9. HDU 4763 Theme Section ( KMP next函数应用 )

    设串为str, 串长为len. 对整个串求一遍next函数,从串结尾开始顺着next函数往前找<=len/3的最长串,假设串长为ans,由于next的性质,所以找到的串肯定满足E……E这种形式, ...

随机推荐

  1. h5实现手机端等级进度条

    h5实现等级进度条 需求如下: 实现一个动画进度条,页面一打开实现一个进度条动画,因为App这个页面会经常改,所以没有使用原审Android或者IOS来实现,希望通过H5来做: 服务器端返回如下数据: ...

  2. PAT B1050 螺旋矩阵 (25 分)

    本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”.所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充.要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N:m ...

  3. grpc & pb 环境配置

    grpc 官方中文文档:http://doc.oschina.net/grpc?t=60140 grpc github仓库:https://github.com/grpc/grpc protobuf ...

  4. ansible role 理解

    1.roles意为角色,主要用于封装playbook实现复用性.在ansible中,roles通过文件的组织结构来展现.

  5. [HAOI2008]排名系统 & [Zjoi2006]GameZ游戏排名系统 BZOJ1862&BZOJ1056

    分析: 平衡树裸题,(学完LCT感觉自己不会普通的Splay了...),维护每个节点的权值大小顺序,和时间戳顺序,之后map维护一下是否存在过,(懒得写字符串hash了). 附上代码: #includ ...

  6. R 语言的Dataframe常用操作

    上节我们简单介绍了Dataframe的定义,这节我们具体来看一下Dataframe的操作 首先,数据框的创建函数为 data.frame( ),参考R语言的帮助文档,我们来了解一下data.frame ...

  7. 20155204 王昊《网络对抗技术》EXP1 PC平台逆向破解

    20155204 王昊<网络对抗技术>EXP1 PC平台逆向破解 (一)实验内容 一.掌握NOP.JNE.JE.JMP.CMP汇编指令的机器码 NOP:NOP指令即"空指令&qu ...

  8. Python的进制等转换

    To 十进制 二进制: >>> int('110', 2) -> 6 八进制: >>> int('10', 8) -> 8 十六进制: >> ...

  9. Qt 的线程与事件循环

    Qt 的线程与事件循环

  10. HTML 中使 footer 始终处于页面底部

    通常在页面中,需要使页脚 footer 部分始终处于底部.当页面高度不够 100% 时, footer 处于页面最底部,当页面内容高于 100% 时,页脚元素可以被撑到最底部. 方法一:绝对定位 &l ...