玄武密码

你。 提交于 2019-11-30 19:34:15

https://loj.ac/problem/10058

题目描述

  给出一个模式串和若干匹配串,求每个匹配串在模式串中前缀的最大匹配长度。

思路

  显然,题意理清楚之后这就是一道几乎是AC自动机的模板题。不过还需要稍稍改一些,首先我们已知N、M的范围,显然对于M进行匹配是不行的,不过我们考虑在一次模式串的匹配串中处理出所有信息。我们如果匹配到k位,那么nxt[k]以及nxt[nxt[k]]等都可以匹配,我们把这些点做一个标记,输出答案是统计这个标记到哪里即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e7+10;
int ch[MAXN][4],tot,nxt[MAXN],ans;
char ss[MAXN],s[100005][110];
bool f[MAXN];
map<char,int>mp;
void clear()
{
    memset(ch,0,sizeof(ch));
    tot=1;
    for(int i=0;i<4;i++)
        ch[0][i]=1,ch[1][i]=0;
}
void insert(char *s)
{
    int u=1,len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int c=mp[s[i]];
        if(!ch[u][c])ch[u][c]=++tot;
        u=ch[u][c];
    }
}
void bfs()
{
    queue<int>q;
    for(int i=0;i<4;i++)
        ch[0][i]=1;
    q.push(1);nxt[1]=0;
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(int i=0;i<4;i++)
        {
            if(!ch[u][i])ch[u][i]=ch[nxt[u]][i];
            else
            {
                q.push(ch[u][i]);
                int v=nxt[u];
                while(v&&!ch[v][i])v=nxt[v]; 
                nxt[ch[u][i]]=ch[v][i];
            }
        }
    }
}
void find(char *s)
{
    int u=1,len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int c=mp[s[i]];
        int k=ch[u][c];
        while(k>1)
        {
            if(f[k])break ;        //如果到已标记的地方就停止,避免重复标记 
            f[k]=1;            //对能匹配到的所有点进行标记 
            k=nxt[k];
        }
        u=ch[u][c];
    }
}
int get(char *s)
{
    int u=1,len=strlen(s),ans=0;
    for(int i=0;i<len;i++)
    {
        int c=mp[s[i]];
        u=ch[u][c];
        if(f[u])ans=i+1;    //查找 
    }
    return ans;
}
int main() 
{
    int n,m;
    mp['E']=0;mp['S']=1;mp['W']=2;mp['N']=3;
    clear();
    scanf("%d%d",&m,&n);
    scanf(" %s",ss);
    for(int i=1;i<=n;i++)
    {
        scanf(" %s",s[i]);
        insert(s[i]);
    }
    bfs();
    find(ss);
    for(int i=1;i<=n;i++)
        printf("%d\n",get(s[i]));
    return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!