CF #Manthan, Codefest 16 C. Spy Syndrome 2 Trie
题目链接:http://codeforces.com/problemset/problem/633/C
大意就是给个字典和一个字符串,求一个用字典中的单词恰好构成字符串的匹配。
比赛的时候是用AC自动机写的,就是对于trie中每一个节点,判断是否为终结点,以及当前字符所在位置p减去trie中这个节点的深度也即某一单词的长度l,判断dp[p-l]是否可以被构成,可以的话直接break并且标记当前dp值。
赛后想了想,其实直接一个trie就行了,每个单词才1000的长度,又想起来我去年给人讲过类似的问题,当时我自己非常清楚这种单词构成用个简单的tire来搞就行。怎么比赛的时候就写了个AC自动机了呢。
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <string> 5 #include <string.h> 6 #include <stdio.h> 7 #include <math.h> 8 #include <stdlib.h> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 #include <ctime> 14 #include <numeric> 15 #include <cassert> 16 17 using namespace std; 18 const int N=100001; 19 string dic[N]; 20 char str[N],pat[N]; 21 int mark[N]; 22 const int CHARSET=26,BASE='a',MAX_NODE=1000001; 23 struct Trie { 24 int tot,root,child[MAX_NODE][CHARSET]; 25 int flag[MAX_NODE]; 26 Trie(){ 27 init(); 28 } 29 void init(){ 30 root=newNode(); 31 } 32 int newNode() { 33 ++tot; 34 memset(child[tot],0,sizeof(child[tot])); 35 flag[tot]=0; 36 return tot; 37 } 38 void insert(const char *str,int id){ 39 int *cur=&root; 40 for (const char *p=str;*p;++p){ 41 cur=&child[*cur][*p-BASE]; 42 if (*cur==0) 43 *cur=newNode(); 44 } 45 flag[*cur]=id; 46 } 47 void query(int x){ 48 int *cur=&root; 49 for (int i=x;i>=1;i--){ 50 char ch=str[i]; 51 cur=&child[*cur][ch-BASE]; 52 if ((*cur)==0) break; 53 if (flag[*cur]&&mark[i-1]!=-1){ 54 mark[x]=flag[*cur]; 55 break; 56 } 57 } 58 } 59 }trie; 60 int main () { 61 int n; 62 scanf("%d",&n); 63 scanf("%s",str+1); 64 int m; 65 scanf("%d",&m); 66 for (int i=1;i<=m;i++) { 67 scanf("%s",pat); 68 dic[i]=string(pat); 69 int len=dic[i].length(); 70 for (int j=0;j<=len;j++) 71 if (pat[j]>='A'&&pat[j]<='Z') 72 pat[j]+='a'-'A'; 73 trie.insert(pat,i); 74 } 75 memset(mark,-1,sizeof mark); 76 mark[0]=0; 77 for (int i=1;i<=n;i++){ 78 trie.query(i); 79 } 80 vector<int> ret; 81 int now=n; 82 while (now>0) { 83 ret.push_back(mark[now]); 84 now-=dic[mark[now]].length(); 85 } 86 for (int i=(int)ret.size()-1;i>=0;i--) { 87 printf("%s ",dic[ret[i]].c_str()); 88 } 89 return 0; 90 }