UVA 11732 - strcmp() Anyone? 字典树
传送门:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832
题目大意:
给定strcmp实现如下:
int strcmp(char *s, char *t) { int i; for (i=0; s[i]==t[i]; i++) if (s[i]=='\0') return 0; return s[i] - t[i]; }
给定n个字符串,若两两比较一次,需要比较多少次?如that和than需要7次
大牛都去比赛了。渣渣只好继续敲代码练习。QAQ
第一次写左儿子右兄弟表示法,基本上参考大神的。
#include<cstdio> #include<cstring> const int MAXN = 4000 * 1000 + 10; const int MAXLEN = 26; char word[1024]; struct Trie { int son[MAXN]; // 第i个结点的左儿子编号 int brother[MAXN]; // 第i个结点的右兄弟编号 char ch[MAXN]; // 为第i个结点上的字符 int tot[MAXN]; // 第i个结点为根的子树包含的叶结点总数 int flag[MAXN]; //相同字符串的个数 int sz; // 结点总数 long long ans; void init() { sz=1; ans=0; tot[0] = son[0] = brother[0] = flag[0] = 0; } void insert(char *s) { ans+=tot[0]; //每插入一个总要和头结点比较 tot[0]++; int len=strlen(s); int u=0,v; for(int i=0;i<len;i++) { bool find=false; for(v=son[u];v!=0;v=brother[v]) if(ch[v]==s[i]) { find=true; break; } if(!find) { v=sz++; tot[v]=0; flag[v]=0; ch[v]=s[i]; brother[v]=son[u]; son[u]=v; //插入头部 son[v]=0; } u=v; ans=ans+tot[u]*2; //需要比较相等和不是'\0' tot[u]++; } if(flag[v])ans+=flag[v];//统计相同字符串的个数 flag[v]++; } }trie; int main() { int kase = 1; int n; while(scanf("%d", &n) && n) { trie.init(); for(int i = 0; i < n; i++) { scanf("%s", word); trie.insert(word); } printf("Case %d: %lld\n", kase++, trie.ans); } return 0; }
新 blog : www.hrwhisper.me