1. 程式人生 > >Codeforces 633C Spy Syndrome 2 【Trie樹】+【DFS】

Codeforces 633C Spy Syndrome 2 【Trie樹】+【DFS】

print net bool void bre ret 給定 pri mar

<題目鏈接>

題目大意:
給定一個只有小寫字母組成的目標串和m個模式串(裏面可能有大寫字母),記目標串反過來後的串為S,讓你從m個模式串中選出若幹個組成S串(不區分大小寫)。輸出任意一種方案。

解題分析:
將所有單詞倒著建好Trie樹後(字母忽略大小寫),直接在Trie樹上跑DFS,記錄下所有符合條件的單詞序號,然後輸出即可。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const
int N =1e6+10; 7 const int M =1e5+10; 8 int n,m; 9 char s[M],word[M][1005]; 10 int trie[N][27],mark[N],ans[M],cnt,tot; 11 void Insert(char *str,int ord){ 12 int now=0,len=strlen(str); 13 for(int i=len-1;i>=0;i--){ //對這些單詞進行逆序插入 14 int to; 15 if(str[i]>Z)to=str[i]-
a; //忽略單詞的大小寫 16 else to=str[i]-A; 17 if(!trie[now][to]) 18 trie[now][to]=++tot; 19 now=trie[now][to]; 20 } 21 mark[now]=ord; //記錄下該單詞的編號 22 } 23 bool dfs(int loc){ 24 if(s[loc]==\0){ //搜索結束 25 for(int i=0;i<cnt;i++){ 26 printf("
%s%s",word[ans[i]],i==cnt-1?"\n":" "); 27 } 28 return true; 29 } 30 int now=0; 31 for(int i=loc;i<n;i++){ 32 int to=s[i]-a; 33 if(!trie[now][to])break; //如果不符合,說明這種搜索的情況不符,直接結束跳出 34 now=trie[now][to]; 35 if(mark[now]){ //如果搜到了單詞庫中完整的單詞 36 ans[cnt++]=mark[now]; //記錄下該單詞的序號 37 if(dfs(i+1))return true; //繼續向下搜索 38 cnt--; //如果之前的情況都不符合,這裏進行回溯,繼續對下一個字符進行搜索 39 } 40 } 41 return false; 42 } 43 int main(){ 44 tot=cnt=0; 45 scanf("%d%s",&n,s); 46 scanf("%d",&m); 47 for(int i=1;i<=m;i++){ 48 scanf("%s",word[i]); 49 Insert(word[i],i); 50 } 51 dfs(0); 52 return 0; 53 }

2018-11-03

Codeforces 633C Spy Syndrome 2 【Trie樹】+【DFS】