1469:似乎在梦中见过的样子
作者:互联网
题干解析
- 没事闲的,找到了本题背景 神秘幽蓝的传送门,本题背景
太好看啦没啥用,总结出来就是在一个字符串中找前后长>=k的字符串,中间还要有空。
具体思路
- 寻找前后缀是极其明显的KMP,我们《只需》在正常KMP的基础上,将每次需寻找前后缀的字符串,并且枚举起始与终点出来,再用KMP找。(配合代码食用效果更佳)
代码
// jqsh 2021.4.6 22:43
#include<bits/stdc++.h>
using namespace std;
int n,m,p[150007],ans;
char a[200007];
void pre(){ //话说我为啥要用函数?
for(int k=1;k<=n-(m<<1);k++){ //枚举
int j=k-1;
for(int i=k;i<=n;i++) p[i]=k-1;
for(int i=k+1;i<=n;i++){// KMP
while(j>k-1&&a[i]!=a[j+1]) j=p[j];
if(a[i]==a[j+1]) j++;
p[i]=j;
// 这段是被屏蔽的那段,如不改,会超时。
int t=j;
while(t-k+1>=i-t) t=p[t]; //保证中间有空
if(t-k+1>=m) ans++; //达到要求,累加
}
/* j=k-1; 这段单独开会超时
for(int i=k+1;i<=n;i++){
while(j>k-1&&a[i]!=a[j+1]) j=p[j];
if(a[i]==a[j+1]) j++;
while(j-k+1>=i-j) j=p[j];
if(j-k+1>=m) ans++;
} */
}
return;
}
int main(){
scanf("%s",a+1);
scanf("%d",&m);
n=strlen(a+1);
pre();
printf("%d\n",ans);
return 0;
}
标签:int,KMP,++,while,1469,ans,字符串,样子,梦中见 来源: https://blog.csdn.net/jqsh_/article/details/115473079