POJ3630——简单Trie树
生活随笔
收集整理的這篇文章主要介紹了
POJ3630——简单Trie树
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這個題的意思是說,給出一些字符串,判斷是否有字符串是另一個字符串的前綴,當然可以用排序水過,不過這個題拿來練習一下Trie樹不錯。
這個題在poj的discuss上好多人說必須要靜態建樹,估計都是用了指針實現的。。不過競賽中最好不要用指針,所以這里用了劉汝佳大神的數組實現方法,其實Trie樹最重要的是每個節點的sz值,以及val值,ch【】【】數組只是作為index來查詢有沒有這個字符,所以用數組實現時,把ch【】【】數組定義在main外面,多case的話每個case定義一個Trie就好了。。。如果把ch【】【】數組定義在結構體里面就沒辦法動態建樹了。。。為此re,wa,了無數發。。。
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<map> #include<vector> #include<cmath> #define eps 1e-8 using namespace std;const int maxn = 10010; typedef long long ll; const int maxnode = 1e5+10,sigma_size =10;//maxnode和sigma_size的大小要隨題意更改 int ch[maxnode][sigma_size]; int val[maxnode]; struct Trie {int sz;Trie(){sz = 1;memset(ch[0],0,sizeof(ch[0]));}int idx(char c) {return c - '0';}bool insert(char *s){int u = 0,n = strlen(s);int mark = 0;for(int i = 0; i < n; ++i){int c = idx(s[i]);if(!ch[u][c]){mark = 1;//這是一個新的節點,說明到現在為止,這個串新開辟了位置,肯定不是之前某個串的前綴memset(ch[sz],0,sizeof(ch[sz]));val[sz] = 0;ch[u][c] = sz++;}u = ch[u][c];if(val[u]) return false;//遇到了之前某個串的結尾。。肯定不符合題意啦。返回false}val[u] = 1;if(!mark) return false;//到插入整個字符了還沒有開辟新位置,顯然新插入的字符串是之前某個串的前綴return true;} }; char s[maxn];int main() {//freopen("in","r",stdin);int T;scanf("%d",&T);while(T--){int n;bool flag = true;scanf("%d",&n);Trie t;for(int i = 0; i < n; ++i){scanf("%s",s);if(flag) flag = t.insert(s);}if(!flag) puts("NO");else puts("YES");} }?
轉載于:https://www.cnblogs.com/Norlan/p/4759515.html
總結
以上是生活随笔為你收集整理的POJ3630——简单Trie树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ 2186 Popular Cow
- 下一篇: 第一百零四天 how can I 坚持