您的位置:首页 > 其它

UVA 11732 - strcmp() Anyone? 字典树

2013-10-27 10:33 323 查看
传送门: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: