标签:GDUT 21 int 排位赛 tr cnt common test suffix
题意
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
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。