其他分享
首页 > 其他分享> > Luogu P2292 [HNOI2004]L语言

Luogu P2292 [HNOI2004]L语言

作者:互联网

Portal(传送门)


解析


方法一:类dp

思路就是把句子上从上一个能划分的位置开始往后能连续划分单词的位置打上标记,最开始的位置是0,然后根据标记进行转移,找到最远能到达的位置即为答案

Code

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
int n,m,rot,trie[205][26];
char word[15],sent[1500005];
bool book[205],vis[1500005];
void insert(char s[])
{
    int u=0,len=strlen(s+1);
    for(int i=1;i<=len;i++)
    {
        int v=s[i]-'a';
        if(!trie[u][v]) trie[u][v]=++rot;
        u=trie[u][v];
    }
    book[u]=1;
    return;
}
int find(char s[])
{
    int u=0,l=0,len=strlen(s+1);
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=len;i++)
    {
        int v=s[i]-'a';
        if(!trie[u][v]) break;
        u=trie[u][v];
        if(book[u]) vis[i]=1;
    }
    for(int i=1;i<=len;i++)
    {
        if(!vis[i]) continue;
        else l=i;
        int u=0;
        for(int j=i+1;j<=len;j++)
        {
            int v=s[j]-'a';
            if(!trie[u][v]) break;
            u=trie[u][v];
            if(book[u]) vis[j]=1;
        }
    }
    return l;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        cin>>(word+1);
        insert(word);
    }
    for(int i=1;i<=m;i++)
    {
        cin>>(sent+1);
        printf("%d\n",find(sent));
    }
    return 0;
}

方法二:记忆化搜索

思路与方法一有相似之处,搜索能划分单词的位置并打上标记,每次用到达的位置更新答案即可

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
int n,m,l,rot,trie[205][26];
char word[15],sent[1500005];
bool book[205],vis[1500005];
void insert(char s[])
{
    int u=0,len=strlen(s+1);
    for(int i=1;i<=len;i++)
    {
        int v=s[i]-'a';
        if(!trie[u][v]) trie[u][v]=++rot;
        u=trie[u][v];
    }
    book[u]=1;
    return;
}
void dfs(char s[],int x,int len)
{
    if(vis[x]) return;
    vis[x]=1;
    int u=0,i=x;
    l=max(l,i-1);
    while(i<=len)
    {
        int v=s[i]-'a';
        if(!trie[u][v]) break;
        u=trie[u][v];
        i++;
        if(book[u]) dfs(s,i,len);
    }
    return;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        cin>>(word+1);
        insert(word);
    }
    for(int i=1;i<=m;i++)
    {
        cin>>(sent+1);
        l=0;
        memset(vis,0,sizeof(vis));
        dfs(sent,1,strlen(sent+1));
        printf("%d\n",l);
    }
    return 0;
}

标签:word,int,Luogu,单词,HNOI2004,P2292,匹配,include,sent
来源: https://www.cnblogs.com/Hawking-llfz/p/11472575.html