其他分享
首页 > 其他分享> > GDUT-21级排位赛第一场 - F. A Poet Computer(字典树)

GDUT-21级排位赛第一场 - F. A Poet Computer(字典树)

作者:互联网

题意

The ACM team is working on an AI project called (Eih Eye Three) that allows computers to write poems. One of the problems they stumbled upon is finding words with the same suffix. The ACM team constructed a dictionary of words, They are interested only in the longest common suffix, That is, a suffix common to three or more words in the dictionary… A suffix is any substring that starts from some arbitrary position in the string and reaches the end of the string. As the ACM team was also preparing for the ACM-TCPC2015 contest, they figured that the contestants can help in solving this problem. Your task is to write a program that finds a longest common suffix in a dictionary of words. An entry in the dictionary is a word of English letters only. Small letters are the same as capital letters. You can assume that there is exactly one unique solution for every test case.

输入格式

The first line of the input contains an integer T, the number of test cases. Each test case starts with a line containing one integer K, then K lines follow, each containing one string “Si” that represents an entry in the dictionary. 0 < T ≤ 50 |Si| ≤ 100 0 < K ≤ 1000

输出格式

For each test case, print on the first line “Case c:” where ‘c’ is the test case number. On the second line you should print an integer denoting the length of the longest common suffix and another integer denoting how many words have the suffix appeared in.

样例1

Input Output
2
4
cocochannel
chrisschannel
MBCchannel
controlpanel
5
superman
batman
ironman
chrissbrown
MyCrown
Case 1:
7 3
Case 2:
3 3

思路

字典树模板题,题目要我们求最长common后缀的长度,以及拥有这个后缀的字符串(要求至少3人相同的后缀才能算是common)。我们可以把每一个输入的字符串逆序插入字典树,然后搜索字典树。

注意计数器是在循环里面加一,因为我们要统计的是拥有该后缀的字符串数量,而不是某一个单词的数量。

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 5 + 1e5;

int tr[N][26], cnt[N], idx;
int maxl, pl;

int id(char c) {
    if (c >= 'a' && c <= 'z') return c-'a';
    else return c-'A';
}

void insert(char * s) {
    int n = strlen(s+1);
    int u = 1;
    for (int i = n; i >= 1; i--) { // 逆序建字典树
        int t = id(s[i]);
        if (!tr[u][t]) tr[u][t] = ++idx;
        u = tr[u][t];
        cnt[u]++; // 求前缀后缀的话应该在循环内加一,而不是在循环外
    }
}

void dfs(int u, int l) {
    if (l > maxl && cnt[u] >= 3) {
        maxl = l;
        pl = cnt[u];
    } else if (l == maxl && cnt[u] >= 3) {
        pl = max(pl, cnt[u]);
    }
    for (int i = 0; i < 26; i++) {
        if (tr[u][i]) {
            // cout << tr[u][i] << endl;
            dfs(tr[u][i], l+1);
        }
    }
}

int main() {
    int t;
    scanf("%d", &t);
    int kase = 1;
    while (t--) {
        memset(tr, 0, sizeof tr);
        memset(cnt, 0, sizeof cnt);
        idx = 1; maxl = 0; pl = 0; // maxl:maxLength pl:amount of people
        int k; scanf("%d", &k);
        char s[105];
        for (int i = 1; i <= k; i++) {
            scanf("%s", s+1);
            insert(s);
        }
        dfs(1, 0); //
        if (maxl == 0) {
            printf("Case %d:\n", kase++);
            printf("0 %d\n", k);
        } else {
            printf("Case %d:\n", kase++);
            printf("%d %d\n", maxl, pl);
        }
    }
}

标签:GDUT,21,int,排位赛,tr,cnt,common,test,suffix
来源: https://www.cnblogs.com/zenghaifan/p/16068131.html