Codeforces 6225B KMP

题目: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\n",cnt-ans);
    return 0;
}
posted @ 2016-03-20 15:14  HARD_UNDERSTAND  阅读(130)  评论(0编辑  收藏  举报