您的位置:首页 > 其它

CSU - 1115 最短的名字(字典树)

2017-08-03 10:23 253 查看
点我看题

题意:找出每个字符串的公共前缀的下一个位置,计算这些长度之和.

分析;基础字典树.写的时候一直在re,数组开的太大,但是没有给出name的最长,只能估计了.

参考代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>

using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn = 1e3+5;
const int maxm = 1e6;
int n;
//char name[10005];
char name[1005][10005];
struct TrieTree{
int cnt;//当前字母出现的次数
int child[26];//子树
};
TrieTree tt[500005];
int tsize;
int ans;

void init()
{
tt[0].cnt = 0;
mem(tt[0].child,0);
tsize = 1;
}

void TrieInsert( char name[])
{
int p = 0;
int rt = 0;
while( name[p] != '\0')
{
int id = name[p]-'a';
if( tt[rt].child[id] == 0)//子树结点不存在
{
tt[tsize].cnt = 0;
mem(tt[tsize].child,0);
tt[rt].child[id] = tsize++;
}
tt[rt].cnt++;
rt = tt[rt].child[id];
p++;
}
}
/*
int TrieSearch( int rt, int deep)
{
for( int i = 0; i < 26; i++)
{
if( tt[rt].child[i] != 0)
{
if( tt[rt].cnt == 1)
ans += deep;
else
TrieSearch(tt[rt].child[i],deep+1);
}
}
}
*/

int TrieSearch( char name[])
{
int p = 0;
int rt = 0;
while( name[p] != '\0')
{
int id = name[p]-'a';
if( tt[rt].cnt == 1)
return p;
rt = tt[rt].child[id];
p++;
}
return 0;
}

int main()
{
int T;
scanf("%d",&T);
while( T--)
{
init();
scanf("%d",&n);
/* for( int i = 1; i <= n; i++)
{
scanf("%s",name);
TrieInsert(name);
}

ans = 0;
TrieSearch(0,0);
*/
for( int i = 1; i <= n; i++)
{
scanf("%s",name[i]);
TrieInsert(name[i]);
}

ans = 0;
for( int i = 1; i <= n; i++)
ans += TrieSearch(name[i]);
printf("%d\n",ans);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: