标签:
2 3 911 97625999 91125426 5 113 12340 123440 12345 98346
NO YES
解析:求是否为非前缀串(即任意串的前缀都不是一个已有的串)。在建Trie树时,只标记串的最后一个字符,然后查询时,看每个串的中间是否存在被标记的点即可。
AC代码:
#include <bits/stdc++.h> using namespace std; const int maxnode = 100000 * 10 + 5; const int sigma_size = 10; struct Trie{ int ch[maxnode][sigma_size]; int val[maxnode]; int sz; void clear(){ sz = 1; memset(ch[0], 0, sizeof(ch[0])); } //初始只有一个根节点 int idx(char c){ return c - '0'; } void insert(string s){ int u = 0, n = s.size(); for(int i=0; i<n; i++){ int c = idx(s[i]); if(!ch[u][c]){ memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] ++; //只标记串尾的字符 } bool find(string s){ int u = 0, n = s.size(); for(int i=0; i<n; i++){ int c = idx(s[i]); if(val[u]) return false; //在一个串的中间出现了已经标记的点 u = ch[u][c]; } return true; } }; Trie T; vector<string> S; int main(){ #ifdef sxk freopen("in.txt", "r", stdin); #endif // sxk int t, n; string s; scanf("%d", &t); while(t--){ S.clear(); T.clear(); //不要忘了初始化 scanf("%d", &n); for(int i=0; i<n; i++){ cin>>s; T.insert(s); S.push_back(s); } int cnt = S.size(); int i; for(i=0; i<cnt; i++){ if(!T.find(S[i])) break; } puts(i < cnt ? "NO" : "YES"); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u013446688/article/details/46858353