poj 3630 Phone List(Trie)

来源:互联网 发布:nginx只允许访问index 编辑:程序博客网 时间:2024/06/11 04:48

这道题可以通过排序后,对于每个串只需与其前一个串与后一个串做比较来查前缀得出答案。


我采用的是字典树(Trie), 昨天学的是动态建立的树,导致TLE。 然后学习了一下静态建立字典树。

思路:插入串时检查当前插入串是不是之前已插入串的前缀,以及检查已插入串是不是当前插入串的前缀。


#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;const int NUM = 10;const int N = 100005;typedef struct Trie{    Trie* next[NUM];    int cnt;    void init()    {        memset(next, NULL, sizeof(next));        cnt = 0;    }};Trie pool[N], *root;int sz;int flag;void getNode(Trie* p){    p->init();}void init(){    root = &pool[0];    getNode(root);    root->init();    sz = 1;}void myInsert(char* str){    Trie* p = root;    int i = 0;    int tflag = 1;  //用于标记 当前插入串 是某个已插入串的前缀 如 9115678 911    while(str[i])    {        int ch = str[i] - '0';        if(p->next[ch] == NULL)        {            p->next[ch] = &pool[sz++];            getNode(p->next[ch]);            tflag = 0;        }        if(p->cnt)        {            flag = 0; //短串作为当前插入串的前缀,如 911  9115678 则已得答案            return;        }//        p = p->next[ch];        i++;    }    if(tflag) {        flag = 0;  //如果当前插入串 是某个已插入串的前缀,则已得答案    }    p->cnt++;}int main(){    int t;    scanf("%d", &t);    char number[16];    while(t--)    {        init();        if(root == NULL) printf("!");        int n;        scanf("%d", &n);        flag = 1;        for(int i = 0; i < n; i++)        {            scanf("%s", number);            if(flag)             myInsert(number);        }//        if(flag)            printf("YES\n");        else            printf("NO\n");    }    return 0;}


0 0
原创粉丝点击