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 ;
}