Trie UVA 11732 "strcmp()" Anyone?

题目传送门

题意:询问所有字符串的比较次数和(注意for循环内的比较也算)

分析:将所有字符串插入到字典树上,然后结点信息记录有几个字符串,那么每走到一个结点就能知道比较到此时需要的次数。学习到链表存结点

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 4e3 + 5;
const int M = 1e3 + 5;
const int NODE = N * M;
struct Trie	{
	int head[NODE], nex[NODE];
	char ch[NODE];
	int cnt[NODE];
	int sz;
	void clear()	{
		sz = 1;	cnt[0] = head[0] = nex[0] = 0;
	}
	void insert(char *str)	{
		int u = 0, len = strlen (str);
		cnt[0]++;
		for (int i=0; i<=len; ++i)	{
			bool found = false;
			int v;
			for (v=head[u]; v; v=nex[v])	{
				if (ch[v] == str[i])	{
					found = true;	break;
				}
			}
			if (!found)	{       //插入到链表的头结点后一个
				v = sz++;
				cnt[v] = 0;
				ch[v] = str[i];
				nex[v] = head[u];
				head[u] = v;
				head[v] = 0;
			}
			u = v;	cnt[u]++;
		}
	}
	void query(int u, int dep, ll &res)	{
		if (!head[u])	{
			res += cnt[u] * (cnt[u] - 1) * dep;
            return ;
		}
		int sum = 0, tmp = cnt[u];
		for (int v=head[u]; v; v=nex[v])	{
		    //sum += cnt[v] * (cnt[u] - cnt[v]);
            res += cnt[v] * (tmp - cnt[v]) * (dep * 2 + 1);
			tmp -= cnt[v];
        }
        //res += sum / 2 * (2 * dep + 1);
		for (int v=head[u]; v; v=nex[v])	{
			query (v, dep + 1, res);
		}
	}
}trie;
char word[M];

int main(void)	{
	int n, cas = 0;
	while (scanf ("%d", &n) == 1)	{
		if (!n)	break;
		trie.clear ();
		for (int i=0; i<n; ++i)	{
			scanf ("%s", &word);
			trie.insert (word);
		}
		ll ans = 0;
		trie.query (0, 0, ans);
		printf ("Case %d: %lld\n", ++cas, ans);
	}

	return 0;
}

  

时间: 2024-10-10 23:08:30

Trie UVA 11732 "strcmp()" Anyone?的相关文章

左儿子右兄弟Trie UVA 11732 strcmp() Anyone?

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. 分析: 大白上的题目. 听说要用左儿子右兄弟的Trie,比较省空间,顺便学了下. 一边inser

UVA 11732 - strcmp() Anyone?(Trie)

UVA 11732 - strcmp() Anyone? 题目链接 题意:给定一些字符串,要求两两比较,需要比较的总次数(注意,如果一个字符相同,实际上要还要和'\0'比一次,相当比2次) 思路:建Trie树,每次建树过程中,后继后继结点就是相同结点需要比较两次ans + val * 2,否则就是不同结点ans + val,建完树就计算完了 代码: #include <cstdio> #include <cstring> const int N = 1005; const int

uva 11732 - strcmp() Anyone? 不错的Trie题

题解:http://blog.csdn.net/u013480600/article/details/23122503 我的代码一直TLE,,,看了人家的之后,觉得1.链式前向星比较好,2.*depth而不是每过一个节点就计算,这一点很好 我是基本copy别人的代码,自己加了注释,留个记号,随后重写, 这道题同样作为链式前向星的Trie的模板 #include <cstdio> #include <cstring> #include <iostream> using n

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie)

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. 分析: 大白上的题目. 听说要用左儿子右兄弟的Trie,比较省空间,顺便学了下. 开始先建树记录次数,然后再遍历统计,结果错了... 后面参考了Shoutmon巨巨的写法,一边insert一边统计. 代码: /* * Author: illuz <iilluzen[at]gmail.com> *

UVa - 11732 - strcmp() Anyone?

先上题目: strcmp() Anyone? Time Limit:2000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Description J ?strcmp()? Anyone? Input: Standard Input Output: Standard Output strcmp() is a library function in C/C++ which compares two stri

uva 11732 - strcmp() Anyone?(字典树)

题目链接:uva 11732 - strcmp() Anyone? 题目大意:给定n个串,然后两两之间比较,问说总共要比较多少次. 解题思路:字典树,建立出字典树,然后根据字典树的性质在节点记录有多少个字符串包含该节点.因为节点的个数比较多,所以用左孩子右兄弟的方法建立字典树. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long

UVa 11732 &quot;strcmp()&quot; Anyone? (左儿子右兄弟前缀树Trie)

题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832 字符串很多,又很长,如果按照题目的意思两两比较,肯定会TLE,所以要用前缀树(Trie)来解决,当然只是用简单的前缀树也会TLE的, 我们必须对其进行优化,看了

UVA 11732 &quot;strcmp()&quot; Anyone? (Trie)

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832 题意:模拟strcmp()函数,给n个字符串,两两之间进行比较,问需要进行多少次比较? 解析:字符串很多,数据量大,按题意两两比较显然不现实.如果把所有的单词插入到一棵Trie里面会怎么样呢?考虑than和that对应的结点,than和that的前3个字符是一样的,但第4个

UVA 11732(&quot;strcmp()&quot; Anyone?-Trie与左兄弟右儿子)

"strcmp()" Anyone? strcmp() is a library function in C/C++ which compares two strings. It takes two strings as input parameter and decides which one is lexicographically larger or smaller: If the first string is greater then it returns a positiv