这题说的是给了一个模板串 然后又给了一个串 需要找出类似的按个模板串 , 改相等的位置要相等 该大于的位置到大于
我们将模板串做好失配指针就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; }
时间: 2024-11-15 07:06:13