Shortest Prefixes【trie模板题】

来源:互联网 发布:用友软件供应商 编辑:程序博客网 时间:2024/06/06 05:50

字典树入门题

题意:
任何字符串不能是其余字符串的前缀(跟哈夫曼编码一样)。
求出每个字符串最短前缀,且可唯一识别该串。
题目链接:
https://odzkskevi.qnssl.com/c6f7f52e0997f01b37ef9c45742fcf77?v=1508370599
Sample Input
1
carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate
Sample Output
carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona

最普通的字典树模板:

#include <bits/stdc++.h>using namespace std;const int maxn = 2e4;         //总结点数const int sigma_size = 26;    //字母表范围struct Trie {    int sz;                        //结点编号    int ch[maxn + 5][sigma_size];  //ch[i][j]表示结点i连向字母j的结点sz值    int val[maxn + 5];             //结点赋值    void clear() {        sz = 1;        memset(ch, 0, sizeof(ch));        memset(val, 0, sizeof(val));    }    void insert(const char *s) {        int u = 0, len = strlen(s);        for(int i = 0; i < len; ++ i) {            int c = s[i] - 'a';            if(!ch[u][c]) ch[u][c] = sz++;            u = ch[u][c];            val[u]++;        }    }    int find(const char *s) {        int u = 0, len = strlen(s);        for(int i = 0; i < len; ++ i) {            int c = s[i] - 'a';            u = ch[u][c];            if(val[u] == 1) return i;        }        return len - 1;    }};Trie trie;char str[2020][30];int main() {    int T;    scanf("%d", &T);    getchar();    getchar();    bool cnt = false;    while(T--) {        trie.clear();        int idx = 0;        if(cnt) putchar('\n'); cnt = true;        while(1) {            gets(str[idx]);            if(strcmp(str[idx], "") == 0) break;            trie.insert(str[idx]);            idx++;        }        for(int i = 0; i < idx; ++ i) {            printf("%s ", str[i]);            int pos = trie.find(str[i]);            for(int j = 0; j <= pos; ++ j)                putchar(str[i][j]);            putchar('\n');        }    }}