POJ 3630 Phone List // Trie

题目描述

POJ 3630 Phone List

解题思路

题目大意:
给一些电话号码,只要存在其中一个号码是另一个号码的前缀,输出“NO”,否则输出“YES”。

将n个号码插入字典树中,对每个节点维护有多少个号码经过此节点,然后再遍历n个号码,判断前缀是否唯一。

PS:这题用动态分配的Trie写貌似会TLE,从此优先考虑用静态数组的方式写了~~

参考代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Trie {
    int next[10];
    int cnt;
} node[100010];

int num;

void init() {
    num = 0;
    memset(node, 0, sizeof(node));
}

int getid(char c) { return c - '0'; }

void insert(char* s) {
    Trie* head = &node[0];
    while (*s) {
        int id = getid(*s++);
        if (head->next[id] == NULL)
            head->next[id] = &node[++num];
        head = head->next[id];
        (head->cnt)++;
    }
}

bool search(char* s) {
    Trie* head = &node[0];
    while (*s) {
        int id = getid(*s++);
        head = head->next[id];
    }
    return (head->cnt) == 1;
}

char phone[10010][11];

int main() {
    int T, n;
    scanf("%d", &T);
    while (T--) {
        init();
        scanf("%d", &n);
        for (int i = 0; i < n; ++i) {
            scanf("%s", phone[i]);
            insert(phone[i]);
        }
        bool ok = true;
        for (int i = 0; i < n; ++i) {
            if (!search(phone[i])) {
                ok = false;
                break;
            }
        }
        printf("%s\n", ok ? "YES" : "NO");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值