字典树,又称trie树,主要用来统计字符串的前缀等等
HDU1671 and POJ 3630
题意是:输入的n串数字中 如果一个串 是 另一个串的前缀,则 YES
建立字典树,标记每个节点的状态:是儿子吗?是终点吗?如果在插入节点时遇到了终点 则包含,如果终点是儿子 则包含。
在添加的过程进行判断
结构体:
struct node
{
int nxt[10];
bool haveson,isleaf;
}tre[maxn];
添加+判断
void add(int now,int x) //now是现在的位置,x是当前处理的字符位置
{
if(x==len)
{
if(tre[now].isleaf||tre[now].haveson)ok=1;
tre[now].isleaf=true;
return;
}
if(tre[now].isleaf) {ok=1;return;}
tre[now].haveson=true;
int v=s[x]-'0';
if(!tre[now].nxt[v]) tre[now].nxt[v]=++cnt; //cnt是数组的下标
add(tre[now].nxt[v],x+1);
}
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int maxn=400050; struct node { int nxt[10]; bool haveson,isleaf; }tre[maxn]; char s[40]; int len,cnt,ok,n,t; void add(int now,int x) { if(x==len) { if(tre[now].isleaf||tre[now].haveson)ok=1; tre[now].isleaf=true; return; } if(tre[now].isleaf) {ok=1;return;} tre[now].haveson=true; int v=s[x]-'0'; if(!tre[now].nxt[v]) tre[now].nxt[v]=++cnt; add(tre[now].nxt[v],x+1); } int main() { scanf("%d",&t); while(t--) { memset(tre,0,sizeof(tre)); cnt=0; scanf("%d",&n); ok=0; while(n--) { scanf("%s",s); // scanf and cin 's speed 3 times len=strlen(s); if(!ok)add(0,0); } if(ok) printf("NO\n"); else printf("YES\n"); } return 0; }