1. 程式人生 > >Codeforces 514C Watto and Mechanism 【Trie樹】+【DFS】

Codeforces 514C Watto and Mechanism 【Trie樹】+【DFS】

<題目連結>

題目大意:
輸入n個單詞構成單詞庫,然後進行m次查詢,每次查詢輸入一個單詞(注意這些單詞只由a,b,c構成),問該單詞庫中是否存在與當前查詢的單詞有且僅有一個字元不同的單詞。

解題分析:
本題將單詞庫中所有的單詞先建trie樹,然後進行容錯數為1的字串匹配,主要是在trie樹上跑DFS,具體步驟見程式碼:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int
M = 6e5+100; 7 typedef long long ll; 8 int n,m; 9 char s[M]; 10 struct Trie{ 11 int cur; 12 Trie *next[3]; 13 Trie(){ 14 cur=-1; 15 for(int i=0;i<=2;i++) 16 next[i]=NULL; 17 } 18 }; 19 Trie *root=new Trie; 20 /*void Insert(){ //為什麼這種建樹方式會超時,而下面的遞迴建樹不會?
21 Trie *now=root; 22 for(int i=0;i<strlen(s);i++){ 23 int to=s[i]-'a'; 24 if(now->next[to]==0) 25 now->next[to]=new Trie; 26 now=now->next[to]; 27 } 28 now->cur=1; 29 }*/ 30 void Trie_Insert(Trie *now,int loc){ //遞迴進行Trie樹的構建 31
if(s[loc]!='\0'){ 32 if(now->next[s[loc]-'a']==NULL) 33 now->next[s[loc]-'a']=new Trie; 34 Trie_Insert(now->next[s[loc]-'a'],loc+1); 35 } 36 else now->cur=1; 37 } 38 bool dfs(Trie *now,int loc,int num){ //now代表當前Trie樹上的節點,loc為當前遍歷到的字串上的字元下標,num代表容錯數 39 if(s[loc]=='\0'){ 40 if(num==0&&now->cur==1)return true; //如果在該字串結束時有且僅有一處錯誤,則符合條件 41 else return false; 42 } 43 if(now->next[s[loc]-'a']!=NULL){ //1.當前字元與Trie樹匹配的情況,只有該字元與當前節點相等,才能繼續向下dfs 44 if(dfs(now->next[s[loc]-'a'],loc+1,num)) 45 return true; 46 } 47 if(num==1){ //2.當前loc處的字元為錯誤字元時,進行容錯處理 48 for(int i=0;i<=2;i++){ 49 if(i!=s[loc]-'a'&&now->next[i]!=NULL) //列舉該節點的子節點a,b,c三種三種字元的不同情況,從中挑選與當前字元不同的情況,繼續向下匹配 50 if(dfs(now->next[i],loc+1,0)) //由於當前loc位置為錯誤字元,所以下面的字元容錯數為0 51 return true; 52 } 53 } 54 return false; 55 } 56 int main(){ 57 scanf("%d%d",&n,&m); 58 for(int i=1;i<=n;i++){ 59 scanf("%s",s); 60 //Insert(); 61 Trie_Insert(root,0); 62 } 63 for(int i=1;i<=m;i++){ 64 scanf("%s",s); 65 if(dfs(root,0,1)) 66 printf("YES\n"); 67 else printf("NO\n"); 68 } 69 return 0; 70 }

 

 

2018-11-01