题目:Codeforces 625B
题意:
给你主串s,模式串t,其中t可能会在s中出现很多次,每次操作可以使s中的一个字符换成’#’,问最少的操作次数。
分析:
简单的KMP,求出模式串t在主串中出现的位置,然后再找出重叠的个数,相减即使答案。
例如主串1212121,模式串121,因为主串中有重叠,只需要12#2#21,两次就可以。
#include<cstdio>
#include<cstring>
const int N=1e5+5;
char s[N],t[N];
int slen,tlen;
int next[N];
int a[N],cnt;
void getNext()
{
int j,k;
j=0;k=next[0]=-1;
while(j<tlen){
if(k==-1||t[j]==t[k])next[++j]=++k;
else k=next[k];
}
}
void KMP_Index()
{
getNext();
int i,j=0;
cnt=0;
for( i=0;i<slen;i++){
while(j&&s[i]!=t[j])j=next[j];
if(s[i]==t[j])j++;
if(j==tlen){
a[cnt++]=i-tlen+1;
j=next[j];
}
}
}
int main()
{
int T;
//freopen("f.txt","r",stdin);
scanf("%s",s);
scanf("%s",t);
tlen=strlen(t);slen=strlen(s);
KMP_Index();
int ans=0;
for(int i=0;i<cnt;){
int k=a[i]+tlen-1;
i++;
while(i<cnt&&a[i]<=k)i++,ans++;
}
printf("%d
",cnt-ans);
return 0;
}