POJ 3630
阿新 • • 發佈:2018-11-19
這道題目依舊是 字典樹題目
大意:
目前有 t 組資料, n 個電話號碼,如果撥打號碼的時候 先撥通了某個號碼,那麼這一串號碼就無法全部撥通,
舉個例子 911 和 9112016652 相比 後者就無法被撥通,因為 911 會先被撥通。
如果都可撥通 輸出 YES 不然輸出 NO
這道題意思很明確,給你 n 個字串,每個字串都不能是另外一個的字首,這裡我們只需要每個字串結尾的時候 對其做一個標記,之後 對於每個新的字串,我們遍歷 從0 --- n-2位,如果發現階數標記,那麼就不能全部撥同,否則就可以。
稍微改動一下 find 和 insert 函式就可以了。
以下 為 AC 程式碼
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 1e5+5; int tree[maxn][30]; int flag[maxn]; int tot; void _insert(char *str) { int rt=0; int len = strlen(str); for(int i=0; i<len; i++) { int id = str[i] - '0'; if(!tree[rt][id]) tree[rt][id]=++tot; rt = tree[rt][id]; } flag[rt] = 1; } bool _find(char *str) { int rt=0; int len = strlen(str); for(int i=0; i<len-1; i++) { int id = str[i] - '0'; rt = tree[rt][id]; if(flag[rt]) return false; } return true; } char ss[maxn][30]; int main() { int n,t; scanf("%d",&t); while(t--) { scanf("%d",&n); memset(flag,0,sizeof(flag)); memset(tree,0,sizeof(tree)); tot=0; for(int i=0;i<n;i++) { scanf("%s",ss[i]); _insert(ss[i]); } int cnt=1; for(int i=0;i<n;i++) { if(!_find(ss[i])) { cnt=0; break; } } if(cnt) printf("YES\n"); else printf("NO\n"); } return 0; }