HDU 1671 (字典树统计是否有前缀)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1671

Problem Description

Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let’s say the phone catalogue listed these numbers:

1. Emergency 911

2. Alice 97 625 999

3. Bob 91 12 54 26

In this case, it’s not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob’s phone number. So this list would not be consistent.

Input

The first line of input gives a single integer, 1 <= t <= 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 <= n <= 10000. Then follows n lines with one unique phone number on each line. A phone number
is a sequence of at most ten digits.

Output

For each test case, output “YES” if the list is consistent, or “NO” otherwise.

Sample Input

2
3
911
97625999
91125426
5
113
12340
123440
12345
98346

Sample Output

NO
YES

Source

2008
“Insigma International Cup” Zhejiang Collegiate Programming Contest - Warm Up(3)

题意:

统计是否有相同的前缀!

代码如下:

#include <cstdio>
#include <cstring>
#include <malloc.h>
#include <iostream>
using namespace std;
#define MAXN 10
typedef struct Trie
{
    int v;//根据需要变化
    Trie *next[MAXN];
    //next是表示每层有多少种类的数,如果只是小写字母,则26即可,
    //若改为大小写字母,则是52,若再加上数字,则是62了
}Trie;
Trie* root;

void createTrie(char *str)
{
    int len = strlen(str);
    Trie *p = root, *q;
    for(int i = 0; i < len; i++)
    {
        int id = str[i]-'0';
        if(p->next[id] == NULL)
        {
            q = (Trie *)malloc(sizeof(Trie));
            q->v = 1;//初始v==1
            for(int j = 0; j < MAXN; j++)
                q->next[j] = NULL;
            p->next[id] = q;
            p = p->next[id];
        }
        else
        {
            p->next[id]->v++;
            p = p->next[id];
        }
    }
     p->v = -1;//若为结尾,则将v改成-1表示
}

int findTrie(char *str)
{
    int len = strlen(str);
    Trie *p = root;
    for(int i = 0; i < len; i++)
    {
        int id = str[i]-'0';
        p = p->next[id];
        if(p == NULL) //若为空集,表示不存以此为前缀的串
            return 0;
        if(p->v == -1)   //字符集中已有串是此串的前缀
            return -1;
    }
    //return p->v;
    return -1;   //此串是字符集中某串的前缀
}
int dealTrie(Trie* T)
{
    //动态字典树,有时会超内存,这是就要记得释放空间了
    if(T==NULL)
        return 0;
    for(int i = 0; i < MAXN; i++)
    {
        if(T->next[i]!=NULL)
            dealTrie(T->next[i]);
    }
    free(T);
    return 0;
}
int main()
{
    int t, n;
    char str[15];
    scanf("%d",&t);
    while(t--)
    {
        int flag = 0;
        root = (Trie *)malloc(sizeof(Trie));
        for(int i = 0; i < MAXN; i++)
            root->next[i] = NULL;
        scanf("%d",&n);
        for(int i = 0; i < n; i++)
        {
            scanf("%s",str);
            if(findTrie(str) == -1)
            {
                flag = 1;
                continue;
            }
            createTrie(str);
        }
        if(flag)
            printf("NO\n");
        else
            printf("YES\n");
        dealTrie(root);
    }
    return 0;
}
时间: 2024-10-18 04:56:48

HDU 1671 (字典树统计是否有前缀)的相关文章

Phone List HDU - 1671 字典树

题意:给出一堆一组一组的数字  判断有没有哪一个是另外一个的前缀 思路:字典树 插入的同时进行判断  不过 当处理一组数字的时候 需要考虑的有两点1.是否包含了其他的序列2.是否被其他序列包含 刚开始开的1e4死活不过  1e5直接过了.. 1 #include<bits/stdc++.h> 2 #include<string> 3 using namespace std; 4 const int maxn=1e5+5; 5 struct Trie{ 6 int size; 7 i

HDU 1251 字典树入门

统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submission(s): 17177    Accepted Submission(s): 7410 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前

HDU 1800 字典树

Flying to the Mars Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10065    Accepted Submission(s): 3270 Problem Description In the year 8888, the Earth is ruled by the PPF Empire . As the popul

hdu 1075 字典树

// hdu 1075 字典树 // // 题目大意: // // 给你一个字典,即有两个字符串,一个是英文,一个是火星文,然后 // 输入一段火星文,要你翻译成英文. // // 解题思路: // // 字典树,查字典嘛,有就输出查到的,没有原样输出.将火星文插入到 // 字典树中,然后在字典输中查找.找到了,输出对应的英文,否则,原样输 // 出. // // 感悟: // // 题目确实很简单,但是,没告诉数据范围啊,导致我一直RE,原来单词 // 可能对应很长的英文啊,找人家ac的开数组

hdu 1251(字典树)

统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submission(s): 29183    Accepted Submission(s): 11454 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的

HDU 5687 字典树入门

Problem C Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1423    Accepted Submission(s): 426 Problem Description 度熊手上有一本神奇的字典,你可以在它里面做如下三个操作: 1.insert : 往神奇字典中插入一个单词 2.delete: 在神奇字典中删除所有前缀等于给

Flying to the Mars HDU - 1800(字典树)

Flying to the Mars HDU - 1800 题目链接:https://vjudge.net/problem/HDU-1800 题目:在8888年,地球由PPF帝国统治.随着人口的增长,PPF需要为新生儿寻找更多的土地.最后,PPF决定攻击统治火星的Kscinow.问题来了!士兵怎么能到达火星? PPF召集他的士兵并询问他们的建议. “匆匆......”一名士兵回答. “闭嘴 !我是否必须提醒你,从这里到火星没有任何道路!“PPF回复道. “飞!”另一个答案. PPF笑道:“聪明的

HDU 5384 字典树、AC自动机

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5384 用字典树.AC自动机两种做法都可以做 1 #include<stdio.h> 2 #include<string.h> 3 #include<string> 4 #include<iostream> 5 using namespace std; 6 struct node{ 7 int cnt; 8 node *next[26]; 9 node(){ 10 c

HDU 5687 字典树插入查找删除

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5687 2016百度之星资格赛C题,直接套用字典树,顺便巩固了一下自己对字典树的理解 1 #include<stdio.h> 2 #include<string.h> 3 struct node{ 4 int next[27]; 5 int cnt; 6 void init(){ 7 cnt = 0;//计数 8 memset(next,-1,sizeof(next)); 9 } 10 };