zoukankan      html  css  js  c++  java
  • POJ3630Phone ListTrie字典树模板题

    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:

    • Emergency 911
    • Alice 97 625 999
    • 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。
    注意审题。

    注意:
    该题没有给出数据范围,数组开到1e4+20会错,开到1e5+20即可。


    详情看代码注释。也可以考虑用链表指针来写。
     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<string.h>
     4 using namespace std;
     5 const int N=1e5+20;
     6 
     7 int ch[N][15],len;//15是开的字符集大小(该题目给的是0-9),该数组用于存储trie树
     8 bool book[N];//==1表示从根节点到该点,所经过的边上字母组成的字符串是实际字符串集合中的元素
     9 char a[15];//题目给出的是n个长度不超过10的字符串
    10 int tot;//总节点数
    11 
    12 //对一个字符集为数字的trie树插入一个字符串s
    13 bool insertt(char *s)  //传入一个字符数组
    14 {
    15 //    int len=strlen(s);
    16     int u=1,flag=0;
    17     for(int i=0; i<len; i++)
    18     {
    19         int c=s[i]-'0';
    20         if(ch[u][c]==0)//表示不存在这条边,所以需要新建一个节点和一条新的边
    21         {
    22             tot++;
    23             ch[u][c]=tot;//tot为总结点数,新建了一个节点
    24         }
    25         else //else if(ch[u][c]!=0)
    26         {
    27             if(i==len-1)//如果遍历到最后一个节点并且没有插入任何一个新节点
    28                 flag=1;//就说明存在前缀关系,返回flag=1
    29         }//else if(i==len-1)
    30         u=ch[u][c];
    31         if(book[u]==1)//经过了某一个有过标记的节点
    32             flag=1;
    33     }
    34     book[u]=1;//一个节点连着接下去的一条边,而不是上一条边
    35     //bo给的赋值为真,给的是最后一个字母所连着的的一个节点
    36     //三个字母是有四个节点
    37     //给当前字符串的最后一个字母进行标记,代表字符串结尾标志
    38     return flag;
    39 }
    40 
    41 int main()
    42 {
    43     int t,n;
    44     scanf("%d",&t);
    45     while(t--)
    46     {
    47         scanf("%d",&n);
    48         tot=1;//代表新建了一个根节点
    49         //一开始不能直接赋值为2,因为可能会是一颗空树
    50         memset(ch,0,sizeof(ch));
    51         memset(book,0,sizeof(book));
    52         int ans=0;
    53         for(int i=0; i<n; i++)
    54         {
    55             scanf("%s",a);
    56             len=strlen(a);
    57             if(insertt(a)==1)
    58                 ans=1;
    59         }
    60         if(ans==0)//不存在前缀关系的情况输出YES,审题
    61             printf("YES\n");
    62         else
    63             printf("NO\n");
    64     }
    65     return 0;
    66 }
     
  • 相关阅读:
    简单 dp 题选做
    UVa11327
    Codeforces Round #641 (div.2) 题解
    新博客
    数位dp的学习
    stl粗略用法
    cf437C The Child and Toy
    poj1995 Raising Modulo Numbers
    Tarjan的学习
    最短路模板
  • 原文地址:https://www.cnblogs.com/OFSHK/p/11779331.html
Copyright © 2011-2022 走看看