zoukankan      html  css  js  c++  java
  • HDU 1671 Phone List [字典树]

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1671

    Phone List

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 28746    Accepted Submission(s): 9368

    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

    题意:给你若干个数字串,判断其中某一个数字串是否为另一个数字串的前缀

    思路:先将所有的数字串插入数字字典树中,然后在依次查询每个数字串的末尾结点是否有子结点,若有则输出NO,否则输出YES

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    using namespace std;
    const int maxnode = 1e6 + 7;
    const int CH = 26;
    int ch[maxnode][CH];
    int val[maxnode];
    int sz ;      //结点总数  初始有一个零结点
    char s[maxnode][27];
    int idx(char c)
    {
        return c - '0';//因为是数字字典树,若是字符字典树则要c-'a';或者c-'A'
    }
    int node()//新建结点
    {
        memset(ch[sz], 0, sizeof(ch[sz]));//将U结点的子结点初始化
        val[sz] = 0;//为零则代表不是插入字符的最后一个
        return sz++;
    }
    void init()
    {
        sz = 0;
        node();//新建一个根结点
    }
    void insert(char *s, int v)//结点的插入
    {
        int u = 0;
        int n = strlen(s);
        for(int i = 0; i < n; i++)
        {
            int c = idx(s[i]);//字符是s[i]是不是结点U的子节点
            if(!ch[u][c])//若不是U结点的子结点 则要新建结点
            {
                ch[u][c] = node();
            }
            u = ch[u][c];//继续更新
        }
        val[u] = v;// 将最后一个结点的子结点标记
    }
    bool ffind(char *s)
    {
        int u = 0;
        int n = strlen(s);
        for(int i = 0; i < n; i++)
        {
            int c = idx(s[i]);
            if(!ch[u][c])//如果 查询长度还没有n个 则代表所查询的字符串在当前的字典树中不存在
                return 0;
            u = ch[u][c];//继续更新 查找
        }
        //跳出循环后   只要查询该U的子结点是否存在即可
        bool flag = false;
        for(int i = 0; i < 10; i++)//因为只有10个数字
        {
            if(ch[u][i])//如果有子结点 代表该数字串为某一个串的前缀
            {
                flag = true;
                break;
            }
        }
        if(flag)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t--)
        {
            init();
            int n;
            scanf("%d", &n);
            for(int i = 0; i < n; i++)
            {
                scanf("%s", s[i]);
                insert(s[i], i + 1);
            }
            bool flag = true;
            for(int i = 0; i < n; i++)
            {
                if(ffind(s[i]))
                {
                    printf("NO
    ");
                    flag = false;
                    break;
                }
            }
            if(flag)
                printf("YES
    ");
        }
        return 0;
    }
  • 相关阅读:
    [备忘]使用Outlook 2010,拖拽大于20M附件发生“附件大小超过了允许的范围”提示的解决方法
    关于Linq to SQL 的“异常详细信息: System.InvalidCastException: 指定的转换无效。”
    [备忘]ie6中href设为javascript:void(0)页面无法提交的解决方法
    [备忘]谷歌员工证实PR值不再更新 呼吁用户关注内容
    今天早上
    C++primer6.20
    Fuzzy KNN
    数值转换
    ArcMap分割图斑
    VS2008 集成openCV过程
  • 原文地址:https://www.cnblogs.com/yyaoling/p/12260429.html
Copyright © 2011-2022 走看看