標籤:ret nbsp 單詞 scan bsp div scanf char pre
<題目連結>
題目大意:
給定一個只有小寫字母組成的目標串和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】