字典树的数组实现 HDU1671

字典树,又称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);
}

  

#include 
#include 
#include 

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

 

转载于:https://www.cnblogs.com/star-and-me/p/6775850.html

你可能感兴趣的:(字典树的数组实现 HDU1671)