1. 程式人生 > >poj1816:Wild Words——題解

poj1816:Wild Words——題解

printf void tar span || get tor 模擬 建立

http://poj.org/problem?id=1816

比較麻煩的trie。

首先你需要選擇針對n還是m建立trie,這裏我選擇了針對n。

那麽就需要面臨卡空間的問題。

這裏提供了一種鏈式前向星的方法能夠當你不會指針trie的時候卡過空間。(做法看代碼吧)

然後針對m進行在trie上的dfs即可。

對於相同字符或?來說,trie下移1位,匹配串移動1位。

對於*來說,trie下移,匹配串移動0~長度位。

(合計這道題就難在模擬上了)

#include<cstdio>
#include<algorithm>
#include<cstring>
#include
<vector> using namespace std; const int maxn=600001; char s[21]; struct node{ char se; int to; int nxt; vector<int>ed; }edge[maxn]; int head[maxn],cnt=0,cnt1=1; void add(int u,char c){ cnt++;cnt1++; edge[cnt].se=c; edge[cnt].to=cnt1; edge[cnt].nxt
=head[u]; head[u]=cnt; return; } void insert(int k){ int u=1; int l=strlen(s); for(int i=0;i<l;i++){ int v=-1; char c=s[i]; for(int j=head[u];j;j=edge[j].nxt){ if(edge[j].se==c){ v=edge[j].to; if(i==l-1)edge[j].ed.push_back(k);
break; } } if(v<0){ add(u,c); v=cnt1; if(i==l-1)edge[cnt].ed.push_back(k); } u=v; } return; } vector<int>ans; int l; void check(int u,int k,int p){ if(k==l){ if(!edge[p].ed.empty()){ for(int i=0;i<edge[p].ed.size();i++){ ans.push_back(edge[p].ed[i]); } } for(int j=head[u];j;j=edge[j].nxt){ int v=edge[j].to; if(edge[j].se==*){ check(v,k,j); } } return; } char c=s[k]; for(int j=head[u];j;j=edge[j].nxt){ int v=edge[j].to; if(edge[j].se==c||edge[j].se==?){ check(v,k+1,j); } if(edge[j].se==*){ for(int q=0;q<=l-k;q++){ check(v,k+q,j); } } } return; } bool t[100001]; int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ scanf("%s",s); insert(i); } for(int j=0;j<m;j++){ scanf("%s",s); ans.clear(); l=strlen(s); check(1,0,0); if(ans.empty()){ printf("Not match"); }else{ memset(t,0,sizeof(t)); sort(ans.begin(),ans.end()); for(int i=0;i<ans.size();i++){ if(!t[ans[i]]){ printf("%d ",ans[i]); t[ans[i]]=1; } } } printf("\n"); } return 0; }

poj1816:Wild Words——題解