题目链接:http://poj.org/problem?id=3630
题意:给一些字符串,问这些字符串是否存在一个字符串是另一个字符串前缀的情况。
思路:trie树解决字符串前缀问题。
我们把每个单词x加入trie树的时候考虑两种情况:
(1) 是否存在已加进去的单词y是x的前缀。
(2) 是否存在已加进去的单词y,x是y的前缀。
我们对每个单词的结尾字母节点进行标记。
对于(1),我们每次到达一个字母节点,去看看这个节点有没有被标记过。
对于(2),我们在当前单词的最后一个字母节点处,先看这个节点之前有没有被访问过,再对这个节点进行操作。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
#define rep(i,j,k) for(int i = j; i <= k; i++ )
#define Rrep(i,j,k) for(int i = j; i >= k; i-- )
#define Clean(x,y) memset(x,y,sizeof(x))
const int maxn = 10;
struct trie
{
int next[100009][maxn];
bool end[100009];
int len;
int root;
bool insert(char s[])
{
int len = strlen(s);
int now = root;
rep(i,0,len-1)
{
int index = s[i] - '0';
if ( i == len-1 && next[now][index] ) return false;
if ( !next[now][index] )
{
next[now][index] = newnode();
}
now = next[now][index];
if ( end[now] ) return false;
}
return end[now] = true;
}
int newnode()
{
return len++;
}
void clear()
{
len = 0;
root = newnode();
Clean(next,0);
Clean(end,false);
}
}a;
char str[10009][12];
int T,n;
int main()
{
cin>>T;
while(T--)
{
a.clear();
cin>>n;
getchar();
bool can = true;
rep(i,1,n)
{
gets(str[i]);
if ( can )
{
can = a.insert( str[i] );
}
}
puts(can?"YES":"NO");
}
return 0;
}