• 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
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    shell中$0,$?,$!等的特殊用法【转载】
    Hadoop操作hdfs的命令【转载】
    libevent的简单应用【转载】
    使用GDB生成coredump文件【转载】
    常用的js代码
    强大的promise
    循环的N种写法
    原型与继承与class
    模块化
    正则RegExp
  • 原文地址:https://www.cnblogs.com/Opaser/p/4817846.html
Copyright © 2020-2023  润新知