计蒜客NOIP模拟赛(2) D2T1 劫富济贫

【问题描述】

吕弗·普自小从英国长大,受到骑士精神的影响,吕弗·普的梦想便是成为一位劫富济贫的骑士。

吕弗·普拿到了一份全国富豪的名单(不在名单上的都是穷人),上面写着所有富豪的名字以及他们的总资产,比如豪特斯·珀去年资产有86E,吕弗·普就会准备抢来资助贫困的伯恩兄弟……

现在吕弗·普做了M次打劫计划,每次要打劫若干个人,他想知道每次能打劫到的总资产是多少

【输入格式】

第一行一个正整数N,代表富豪的个数

接下来N行,每行一个由小写字母组成的字符串Si和一个非负整数Wi,分别代表第i个富豪的名字和第i个富豪的资产数量

然后一个正整数M,代表吕弗·普的打劫次数

接下来M行,每行第一个数为正整数Xi,代表这次要打劫Xi个人,接下来有X个字符串,说明了这Xi个人是谁

【输出格式】

对于每次打劫任务,输出一行一个整数表示打劫到的总资产

如果这次打劫任务中打劫了一个穷人,那就输出-1

【样例输入】

2

a 10

b 20

3

2 a b

1 b

2 a c

【样例输出】

30

20

-1


【数据范围与约定】

对于30% 的数据,输入中每个名字的长度均为1

对于60% 的数据,N,∑Xi<= 100,输入中每个名字的长度<=10

对于100%的数据,N,∑Xi<= 10^5,输入中所有名字的总长度<=2*10^6,Wi<=10^9保证任意两个富豪名字不同,但不保证打劫计划中会不会有重复的人

字典树裸题

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long lol;
 7 int tot=1;
 8 char s[1000001];
 9 int ch[1000001][27],n,m;
10 lol w[1000001],ans;
11 void add(lol d)
12 {int i;
13   int l=strlen(s);
14   int now=1;
15   for (i=0;i<l;i++)
16     {
17       int x=s[i]-'a';
18       if (!ch[now][x])
19     {
20       ch[now][x]=++tot;
21       w[tot]=-1;
22     }
23       now=ch[now][x];
24     }
25   w[now]=d;
26 }
27 lol find()
28 {int i;
29   int l=strlen(s);
30   int now=1;
31   for (i=0;i<l;i++)
32     {
33       int x=s[i]-'a';
34       now=ch[now][x];
35     }
36   return w[now];
37 }
38 int main()
39 {lol d,k,x;
40   int i,j;
41   cin>>n;
42   w[0]=-1;
43   for (i=1;i<=n;i++)
44     {
45       scanf("%s%lld",s,&d);
46       add(d);
47     }
48   cin>>m;
49   for (i=1;i<=m;i++)
50     {
51       scanf("%lld",&k);
52       bool flag=1;
53       ans=0;
54       for (j=1;j<=k;j++)
55     {
56       scanf("%s",s);
57       x=find();
58       if (x==-1)
59         {
60           flag=0;
61           break;
62         }
63       else ans+=x;
64     }
65       if (flag) printf("%lld\n",ans);
66       else printf("-1\n");
67     }
68 }

 

 

 

posted @ 2017-09-08 19:06  Z-Y-Y-S  阅读(489)  评论(0编辑  收藏  举报