1. 程式人生 >實用技巧 >其它 >YbtOJ KMP演算法課堂過關 例4 子串拆分【KMP】

YbtOJ KMP演算法課堂過關 例4 子串拆分【KMP】


YbtOJ KMP演算法課堂過關 例4 子串拆分【KMP】


思路

這道題首先可以發現要找最大字串的子串來看是否有ABA型,然後直接超時,發現可以直接列舉左端點,大的子串可以包含小的右端點子串。於是列舉每一個左端點,然後求next,把這個子串中所有ABA找出來,然後找的過程也可以用 k = n e x t [ k ] k=next[k] k=next[k] 來找,當然一個ABA還要滿足題目中的兩個條件才行。

程式碼

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int lo,nxt[20010],nxt2[20010];
char s[20010],zn[20010];
int ans;
int main()
{
	scanf("%s",s+1);
	cin>>lo;
	int longs=strlen(s+1);
	for(int i=1; i<=longs; i++)
     {
		memset(nxt,0,sizeof(nxt));
     	memset(zn,0,sizeof(zn));
     	for(int j=1; i+j-1<=longs; j++)
     	   zn[j]=s[i+j-1];
     	int k=0,longzn=strlen(zn+1);
     	for(int j=2; j<=longzn; j++)
     	 {
     	 	while(k>0&&zn[k+1]!=zn[j])
     	 	  k=nxt[k];
     	 	if(zn[k+1]==zn[j])
     	 	  k++;
     	 	nxt[j]=k;
		 }
		k=0;
		for(int j=2; j<=longzn; j++)
		 {
		 	while(k>0&&zn[k+1]!=zn[j])
		 	  k=nxt[k];
		 	if(zn[k+1]==zn[j])
		 	  k++;
		 	while(k*2>=j)
		 	  k=nxt[k];
		 	if(k>=lo)
		 	  ans++;
		 }
	 }
	cout<<ans; 
	return 0;
}