ACM: Gym 100935F A Poet Computer - 字典树

Gym 100935F A Poet Computer

Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

standard input/output

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.

Input

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

Output

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.

Sample Input

Input

24cocochannelchrisschannelMBCchannelcontrolpanel5supermanbatmanironmanchrissbrownMyCrown

Output

Case 1:7 3Case 2:3 3
/*/
题意:找最长常见后缀;

单纯的字典树,找后缀数大于等于3,长度尽可能大的后缀。

AC代码:
/*/
#include"algorithm"
#include"iostream"
#include"cstring"
#include"cstdlib"
#include"cstdio"
#include"string"
#include"vector"
#include"queue"
#include"cmath"
using namespace std;
typedef long long LL ;
#define memset(x,y) memset(x,y,sizeof(x))
#define memcpy(x,y) memcpy(x,y,sizeof(x))
#define FK(x) cout<<"["<<x<<"]\n"

struct Trie {
	int v;
	int len;
	Trie *next[26];
} root;

struct Ans {
	int len,num;
} ans,t;

void init() {
	ans.len=ans.num=0;
	t.len=t.num=0;
}

void BuildTree(char *s) {
//	FK("NO");
	int len=strlen(s);
	Trie *p=&root,*q;
	for(int i=len-1; i>=0; i--) {
		int num;
	//	if(!((s[i]<=‘Z‘&&s[i]>=‘A‘)||(s[i]<=‘z‘&&s[i]>=‘a‘)))continue;
		if(s[i]<=‘z‘&&s[i]>=‘a‘)num=s[i]-‘a‘;
		else num=s[i]-‘A‘;
		if(p->next[num]==NULL) {
			q=(Trie *)malloc(sizeof(root));
			q->v=1;
			for(int j=0; j<26; j++) {
				q->next[j]=NULL;
			}
			q->len=p->len+1;
			p->next[num]=q;
			p=p->next[num];
		} else {
			p=p->next[num];
			p->v++;

		}
		if(p->v >= 3&&p->len >= t.len) {
			t.len=p->len;
			t.num=p->v;
		}
	}
}

void DeleteTrie(Trie *T,int k) {
	if (T==NULL) return ;
	for(int i=0; i<26; i++) {
		if(T->next[i]!=NULL) {
			DeleteTrie(T->next[i],k+1);
		}
	}
	if(k==0) {
		for(int i=0; i<26; i++) {
			T->next[i]=NULL;
		}
	} else free(T);
	return ;
}

int main() {
	int T,n;
	char s[205];
	scanf("%d",&T);
	for(int qq=1; qq<=T; qq++) {
		scanf("%d",&n);
		init();
		for(int i=0; i<n; i++) {
		 	cin>>s;
			BuildTree(s);
			if(t.num>=3&&t.len>=ans.len) {
				ans=t;
			}
		}
		printf("Case %d:\n", qq);
		printf("%d %d\n",ans.len,ans.num);
		Trie *p=&root;
		DeleteTrie(p,0);
	}
	return 0;
}

  

时间: 2024-10-29 19:10:21

ACM: Gym 100935F A Poet Computer - 字典树的相关文章

[ACM] hdu 1251 统计难题 (字典树)

统计难题 Problem Description Ignatius近期遇到一个难题,老师交给他非常多单词(仅仅有小写字母组成,不会有反复的单词出现),如今老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每一个提问都是一个字符串. 注意:本题仅仅有一组測试数据,处理到文件结束. Out

Barty&#39;s Computer 字典树

https://nanti.jisuanke.com/t/17122 Barty have a computer, it can do these two things. Add a new string to its memory, the length of this string is even. For given 44 strings a,b,c,da,b,c,d, find out how many strings that can be product by a+s1+b+c+s2

字典树 - 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 on

ACM:统计难题 解题报告-字典树(Trie树)

统计难题 Time Limit:2000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Status Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignati

ACM学习历程—HDU 5536 Chip Factory(xor &amp;&amp; 字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题目大意是给了一个序列,求(si+sj)^sk的最大值. 首先n有1000,暴力理论上是不行的. 此外题目中说大数据只有10组,小数据最多n只有100.(那么c*n^2的复杂度应该差不多) 于是可以考虑枚举i和j,然后匹配k. 于是可以先把所有s[k]全部存进一个字典树, 然后枚举s[i]和s[j],由于i.j.k互不相等,于是先从字典树里面删掉s[i]和s[j],然后对s[i]+s[j]这个

A .Gaby And Addition (Gym - 101466A + 字典树)

题目链接:http://codeforces.com/gym/101466/problem/A 题目: 题意: 给你n个数,重定义两个数之间的加法不进位,求这些数中两个数相加的最大值和最小值. 思路: 字典树.我们首先将前i-1为放入字典树中,然后在查询第i位时,我们去字典树中查询,对每一位进行寻找,找到满足题意的当前位的最大值和最小值,然后继续更新下一位,最后维护总的最大值和最小值即可. 代码实现如下: 1 #include <set> 2 #include <map> 3 #i

CodeFoeces GYM 101466A Gaby And Addition (字典树)

gym 101466A Gaby And Addition 题目分析 题意: 给出n个数,找任意两个数 “相加”,求这个结果的最大值和最小值,注意此处的加法为不进位加法. 思路: 由于给出的数最多有 1e6 个,且每个数的值最大为 1e18 ,又因为特殊的加法运算,我们自然无法用常规的方法解决 注意到这个加法运算可以分配到每一位上进行运算,而且最大为1e18,十九位数,那么我们就可以用字典树来存储每个数,并进行计算,为了将字典树每个结点的深度和数的位数对应起来,我们可以将每个数都处理为19位数,

codeforces gym #101161F-Dictionary Game(字典树+树上删边游戏)

题目链接: http://codeforces.com/gym/101161/attachments 题意: 给一个可以变化的字典树 在字典树上删边 如果某条边和根节点不连通那么这条边也删除 谁没得删就输了 数据范围: $1\leq n \leq 100000$ $1\leq q \leq 100000$ $1\leq |s| \leq 40$ 分析: ac代码: #include<bits/stdc++.h> using namespace std; #define ll long long

ACM学习历程—POJ 3764 The xor-longest Path(xor &amp;&amp; 字典树 &amp;&amp; 贪心)

题目链接:http://poj.org/problem?id=3764 题目大意是在树上求一条路径,使得xor和最大. 由于是在树上,所以两个结点之间应有唯一路径. 而xor(u, v) = xor(0, u)^xor(0, v). 所以如果预处理出0结点到所有结点的xor路径和,问题就转换成了求n个数中取出两个数,使得xor最大. 这个之前用字典树处理过类似问题. 代码: #include <iostream> #include <cstdio> #include <cst