HDU 1671
题意:给出N个串,问如果所有串都不是别的串的前缀串,则输出YES,否则输出NO。
算法:裸的Trie树,直接构建一个N串的Trie树,然后每次对该串进行匹配,如果匹配结果大于1,那么该串必定为2个串以上的前缀,那么就输出NO。
这道题唯一需要主要的就是要释放内存,不然会MLE。
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> #include <cstring> #include <queue> #include <set> #include <vector> #include <stack> #include <map> #include <iomanip> #define PI acos(-1.0) #define Max 2505 #define inf 1<<28 #define LL(x) ( x << 1 ) #define RR(x) ( x << 1 | 1 ) #define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define mp(a,b) make_pair(a,b) #define PII pair<int,int> using namespace std; struct Trie{ Trie *next[11] ; int count ; Trie(){ mem(next ,0) ; count = 0 ; } } ; Trie *root = 0 ; void build(char *a){ int l = strlen(a) ; Trie *p = root ; for (int i = 0 ; i < l ;i ++ ){ int tt = a[i] - '0' ; if(p -> next[tt] == 0){ p -> next[tt] = new Trie() ; } p = p -> next[tt] ; p -> count ++ ; } } int search(char *a){ int l = strlen(a) ; Trie *p = root ; for (int i = 0 ; i < l ; i ++ ){ int tt = a[i] - '0' ; if(p -> next[tt] == 0){ break ; } p = p -> next[tt] ; } if(p -> count > 1)return 1 ; else return 0 ; } char a[10006][111] ; void deleteAll(Trie *p){ for (int i = 0 ; i < 10 ;i ++ ){ if(p -> next[i] != 0){ deleteAll(p -> next[i]) ; } } delete p ; } int main() { int T ; cin >> T ; while( T -- ){ int n ; root = new Trie() ; cin >> n ; for (int i = 0 ; i < n ;i ++ ){ scanf("%s",a[i]) ; build(a[i]) ; } bool flag = 0 ; for (int i = 0 ;i < n ; i ++ ){ if(search(a[i])){ flag = 1 ; puts("NO") ; break ; } } if(!flag)puts("YES") ; deleteAll(root) ; } return 0 ; }
POJ 3630
这两道题是一样的,但是HDU目测数据比较水,我用指针写可以过,但是POJ就T了,然后改成数组的写法才过。
以后还是都写数组的吧。指针还是太耗时了。
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> #include <cstring> #include <queue> #include <set> #include <vector> #include <stack> #include <map> #include <iomanip> #define PI acos(-1.0) #define Max 2505 #define inf 1<<28 #define LL(x) ( x << 1 ) #define RR(x) ( x << 1 | 1 ) #define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define mp(a,b) make_pair(a,b) #define PII pair<int,int> using namespace std; struct T{ int next[11] ; int count ; T(){ mem(next ,0) ; count = 0 ; } } TT[111111] ; int num = 0 ; void build(char *a){ int l = strlen(a) ; int p = 0 ; for (int i = 0 ; i < l ;i ++ ){ int tt = a[i] - '0' ; if(TT[p].next[tt] == 0){ TT[p].next[tt] = ++ num ; } p = TT[p].next[tt] ; TT[p].count ++ ; } } int search(char *a){ int p = 0 ; int l = strlen(a) ; for (int i = 0 ; i < l ;i ++ ){ int tt = a[i] - '0' ; if(TT[p].next[tt] == 0)break ; p = TT[p].next[tt] ; } if(TT[p].count > 1)return 1 ; return 0; } char a[10006][111] ; int main() { int T ; cin >> T ; while( T -- ){ int n ; num = 0 ; for (int i = 0 ;i < 111111 ;i ++ ){ mem(TT[i].next ,0) ; TT[i].count = 0 ; } cin >> n ; for (int i = 0 ; i < n ;i ++ ){ scanf("%s",a[i]) ; build(a[i]) ; } bool flag = 0 ; for (int i = 0 ;i < n ; i ++ ){ if(search(a[i])){ flag = 1 ; puts("NO") ; break ; } } if(!flag)puts("YES") ; } return 0 ; }