题目描述
每个人都有名字,名字都是唯一的不存在重复现象。现在假设名字都是由小写字母组成并且长度不超过10,我们赋予每个名字一个初始价值。价值是正整数并且不超过100,如果第j个人的名字是第i个人的前缀并且前缀长度最大,我们就说j是i的父节点,比如:名字A为:a;名字B为ab;名字C为abc; A是C的前缀,B也是C的前缀,但是B的长度为2比A的长度大,那么B就是C的父节点. 由此规则建树,从叶子节点到根,父节点的价值=父节点本身的价值+孩子节点的价值。 求最后各个名字的价值
输入
一个整数T,代表数据组数
对于每一组数据输入第一行为一个整数N(0<N<=10^5)代表N个名字,第二行为N个名字,第三行为N个名字的价值
名字都是唯一的
对于每一组数据输入第一行为一个整数N(0<N<=10^5)代表N个名字,第二行为N个名字,第三行为N个名字的价值
名字都是唯一的
输出
输出N个对应的名字的价值,按照输入的顺序输出(操作完成后最终价值)
示例输入
1 3 a ab abc 10 20 30
示例输出
60 50 30
提示
大数据输入,建议用scanf
#include <stdio.h>
#include <string.h>
struct node
{
char c;
int e;
int jz;
node *a[26];
}*root,*now;
node *q[100001];
node *add (char *s)
{
char *p = s;
int n;
node *tmp;
while (*p != '\0')
{
n = *p - 'a';
if (now->a[n] == NULL)
{
tmp = new node;
memset(tmp,0,sizeof (*tmp));
tmp->c = *p;
now->a[n] = tmp;
}
now = now->a[n];
p++;
}
now->e = 1;
return now;
}
int js (node *p)
{
int num = 0,i;
if (p->e)
num = p->jz;
for (i = 0;i < 26;i++)
{
if (p->a[i] != NULL)
num += js(p->a[i]);
}
return num;
}
int main()
{
int N;
scanf ("%d",&N);
while (N--)
{
int n,i;
root = new node;
memset(root,0,sizeof (*root));
scanf ("%d",&n);
for (i = 0;i < n;i++)
{
char s[101];
scanf ("%s",s);
now = root;
q[i] = add(s);
}
for (i = 0;i < n;i++)
{
int tmp;
scanf ("%d",&tmp);
q[i]->jz = tmp;
}
for (i = 0;i < n;i++)
{
int num = js(q[i]);
printf ("%d",num);
if (i < n - 1)
printf (" ");
else
printf ("\n");
}
}
return 0;
}