bzoj1819: [JSOI]Word Query电子字典

来源:互联网 发布:软件学院到湖湘公园 编辑:程序博客网 时间:2024/05/12 03:00

传送门
大力建出Trie之后转移。
也就是三种情况:跳过该字符。跳过该Trie数节点,向兄弟节点跳。
注意一个字符串可能有多种方法和字典中字符串匹配。

#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<iostream>#include<algorithm>#define N 200005using namespace std;int a[N][26],vis[N],tag[N],q[N];char s[30];int n,m,tot,len,ans,w,x;void dfs(int x,int y,int f){    if (x>=len&&tag[y]&&!f){w=1; return;}    if (x>=len&&tag[y]&&f){        if (!vis[y]) vis[y]=1,q[++ans]=y;        return;    }    if (x<len&&!f) dfs(x+1,y,1);    if (!f) for (int i=0;i<26;i++)        if (a[y][i]!=-1){            dfs(x,a[y][i],1);            if ('a'+i!=s[x+1]) dfs(x+1,a[y][i],1);        }    if (x>=len) return;    if (a[y][s[x+1]-'a']!=-1) dfs(x+1,a[y][s[x+1]-'a'],f);}int main(){    scanf("%d%d",&n,&m);    tot=1;    for (int i=1;i<N;i++)        for (int j=0;j<26;j++) a[i][j]=-1;    for (int i=1;i<=n;i++){        scanf("%s",&s);        len=strlen(s);        x=1;        for (int j=0;j<len;j++){            if (a[x][s[j]-'a']==-1) a[x][s[j]-'a']=++tot;            x=a[x][s[j]-'a'];        }        tag[x]=1;    }    for (int i=1;i<=m;i++){        for (;ans>0;ans--) vis[q[ans]]=0;        scanf("%s",s+1);        len=strlen(s+1);        ans=w=0;        dfs(0,1,0);        if (w) printf("-1\n"); else printf("%d\n",ans);    }}