hdu4749 kmp改进

这题说的是给了一个模板串 然后又给了一个串 需要找出类似的按个模板串 , 改相等的位置要相等 该大于的位置到大于

我们将模板串做好失配指针就ok了,然后匹配和原来的匹配不同,这个匹配需要的是相对匹配,只要他们的相对位置相同就ok了,每次计算要插入的数在这个匹配中的排位

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int maxn=100005;
int x[maxn],a[maxn],D[26];
int F[maxn];
void getFail(int m)
{
     F[1]=1; F[2]=1;
     for(int i=2; i<=m; i++)
        {
            int j=F[i];
            while( j != 1 && a[i] != a[j]) j = F[ j ];
            F[i+1]=( a[i] == a[j] )? j+1 : 1;
        }
}
int perx[maxn][26],pera[maxn][26];
void init(int n, int m,int k)
{
     memset(perx[0],0,sizeof(perx[0]));
     memset(pera[0],0,sizeof(pera[0]));
     for(int i=1; i<=n; i++)
        {
            for(int j=0; j<=k; j++)
             perx[i][j]=perx[i-1][j];
            perx[i][ x[i] ]++;
        }
     for(int i=1; i<=m; i++)
     {
         for(int j=0; j<=k; j++)
             pera[i][j]=pera[i-1][j];
         pera[i][a[i]]++;
     }
}
bool vis[maxn];
bool jul(int xi, int aj)
{
    int mii=0,ei=0,mij=0,ej=0;
    for(int k=0; k<x[xi]; k++)
        mii+=perx[xi][k]-perx[xi-aj][k];
    ei=perx[xi][ x[xi] ] - perx[ xi - aj ][ x[ xi ] ];
    for(int k=0; k<a[ aj ]; k++)
        mij+=pera[ aj ][ k ];
    ej=pera[ aj ][ a[aj] ];
    return mii==mij&&ej==ei;
}
void find(int n,int m)
{
    int j=1;
    for(int i=1; i<=n; i++)
        {
            while(j!=1&&jul(i,j)==false)j=F[j];
            if(jul(i,j))j++;
            if( j == m + 1 )
                {
                    vis[ i ]=true;j=F[j];
                }
        }
}
int main()
{
    int n,m,k;
    while(scanf("%d%d%d",&n,&m,&k)==3)
    {
        memset(D,0,sizeof(D));
        for(int i=1; i<=n; i++)
            {
                scanf("%d",&x[i]);
                vis[i]=false;
            }
        for(int i=1; i<=m; i++)
            {
                scanf("%d",&a[i]);
                D[a[i]]=1;
            }
        for(int i=1; i<=k; i++)
            D[i]=D[i]+D[i-1];
        for(int i=1; i<=m; i++)
            a[i]=D[a[i]];
        getFail(m);
        init(n,m,k);
        find(n,m);
        int ans=0,loc=m;
        while(loc<=n){
            if(vis[loc]){
                ans++;
                loc+=m;
            }else loc++;
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2015-09-17 22:17  来自大山深处的菜鸟  阅读(244)  评论(0编辑  收藏  举报