计蒜客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 }