UVA - 11732 "strcmp()" Anyone?左兄弟右儿子trie

input

n 2<=n<=4000

s1

s2

...

sn

1<=len(si)<=1000

output

输出用strcmp()两两比较si,sj(i!=j)要比较的次数,结果在long long范围内(相同字符比较两次,不相同字符比较一次,包括‘\0‘)

做法:由于字符集太大,要用左兄弟右儿子的trie保存字符,不用每次都开ch[62]个孩子

 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <map>
 9 #include <set>
10 #include <ctime>
11 #include <cmath>
12 #include <cctype>
13 #define MAX 100000
14 #define LL long long
15 #define mod 20071027
16 struct node
17 {
18     int sz;
19     char val;
20     node*ch[2];            //ch[1]兄弟,ch[0]儿子
21     node()
22     {
23         ch[0]=ch[1]=NULL;
24         sz=0;
25     }
26 };
27 char word[1010];
28 int n,cas=1;
29 long long sum;
30 long long insert(char*s,node*u)
31 {
32     long long sum=0,lastsz=u->sz++;
33     for(;*s||*(s-1);s++)
34     {
35         if(!u->ch[0])            //易错,要先把新建的结点连接到父结点才能往下走,否则新建之后父节点无法再读取到该结点
36         {
37             u->ch[0]=new node;
38             u->ch[0]->val=*s;
39         }
40         for(u=u->ch[0];u->val!=*s;u=u->ch[1])
41         {
42             if(!u->ch[1])
43             {
44                 u->ch[1]=new node;
45                 u->ch[1]->val=*s;
46             }
47         }
48         sum+=lastsz+u->sz;
49         lastsz=u->sz++;
50     }
51     return sum;
52 }
53 void freenode(node*u)
54 {
55     if(u==NULL) return;
56     freenode(u->ch[0]);
57     freenode(u->ch[1]);
58     delete u;
59 }
60 int main()
61 {
62     //freopen("/home/user/桌面/in","r",stdin);
63     while(scanf("%d",&n)==1&&n)
64     {
65         sum=0;
66         node *root=new node;
67         while(n--)
68         {
69             scanf("%s",word);
70             sum+=insert(word,root);
71         }
72         printf("Case %d: %lld\n",cas++,sum);
73         freenode(root);
74     }
75     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
76     return 0;
77 }

my Code

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 #define repf(i,a,b) for(int i=(a);i<=(b);i++)
 8 typedef long long ll;
 9
10 const int N = 0;
11 const int MAXNODE = 4000010;
12
13 int n, cas;
14 ll ans;
15 char str[4001];
16
17 struct STrie {
18     int son[MAXNODE];
19     int bro[MAXNODE];
20     int val[MAXNODE];
21     char ch[MAXNODE];
22     int sz;
23
24     STrie() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }
25     void init() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }
26     // inline int idx(char c) { return c - ‘a‘; }
27
28     void insert(char *s) {
29         int len = strlen(s), u = 0, p;
30         repf (i, 0, len) {
31             // check the brother of u
32             for (p = son[u]; p; p = bro[p]) {
33                 if (ch[p] == s[i])
34                     break;
35             }
36             // cannot find out than insert
37             if (!p) {
38                 p = sz++;
39                 ch[p] = s[i];
40                 bro[p] = son[u];
41                 son[p] = 0;
42                 val[p] = 0;
43                 son[u] = p;
44             }
45             ans += (val[u] - val[p]) * (2 * i + 1);
46             if (len == i) {
47                 ans += val[p] * (2 * i + 2);
48                 val[p]++;
49             }
50             val[u]++;
51             u = p;
52         }
53     }
54 } trie;
55
56 int main() {
57     // ios_base::sync_with_stdio(0);
58     while (~scanf("%d", &n) && n) {
59         trie.init();
60         ans = 0;
61         repf (i, 0, n - 1) {
62             scanf("%s", str);
63             trie.insert(str);
64         }
65         printf("Case %d: %lld\n", ++cas, ans);
66     }
67     return 0;
68 } 

copy Code

时间: 2024-09-30 10:52:37

UVA - 11732 "strcmp()" Anyone?左兄弟右儿子trie的相关文章

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

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

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

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

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?(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 &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 strcmp()函数(左孩子右兄弟表示法)

1 #include<iostream> 2 #include<algorithm> 3 #include<string> 4 #include<cstring> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 4000 * 1000 + 10; 9 int n; 10 long long ans; 11 12 struct Trie 13 { 14 int head[