51Nod 1526 分配 笔名

1526 分配 笔名

题目来源: CodeForces

基准时间限制:1 秒 空间限制:131072 KB 分值: 320 难度:7级算法题

 收藏

 关注

班里有n个同学。老师为他们选了n个笔名。现在要把这些笔名分配给每一个同学,每一个同学分配到一个笔名,每一个笔名必须分配给某个同学。现在定义笔名和真名之间的相关度是他们之间的最长公共前缀。设笔名为a,真名为b,则他们之间的相关度为lcp(a,b)。那么我们就可以得到匹配的质量是每一个同学笔名和真名之间相关度的和。

现在要求分配笔名,使得匹配质量最大。

样例解释:

·        bill → bilbo (lcp = 3)

·        galya → galadriel (lcp = 3)

·        gennady → gendalf (lcp = 3)

·        toshik → torin (lcp = 2)

·        boris → smaug (lcp = 0)

Input

单组测试数据。
第一行有一个整数n (1≤n≤100000),表示班级中同学的数目。
接下来n行,表示每一个同学的真名,每一个名字是非空串,且由小写字母组成。
名字可能重复。
最后n行是老师已经安排好的笔名。每一个笔名是一个非空串,且由小写字母组成。
笔名可能重复。
输入的字符总数目不超过 800000。

Output

输出最大的匹配质量。

Input示例

样例输入1
5
gennady
galya
boris
bill
toshik
bilbo
torin
gendalf
smaug
galadriel

Output示例

样例输出1
11

 1 /*
 2     乱搞
 3     我们可以先用真名建一颗字典树,
 4     然后用笔名在字典树上匹配,标记大于0则 ans++,标记-1
 5     不明原理。。。
 6 */
 7 #include <cstdio>
 8 #include <cstring>
 9
10 const int MAXN=1000010;
11
12 char s[MAXN][11],q[MAXN][11];
13
14 int n,tot,ans;
15
16 int t[MAXN][27],sum[MAXN];
17
18 inline void build(int cnt) {
19     int now=0;
20     int len=strlen(s[cnt]);
21     for(int i=0;i<len;++i) {
22         int x=s[cnt][i]-‘a‘+1;
23         if(!t[now][x]) t[now][x]=++tot;
24         now=t[now][x];
25         ++sum[now];
26     }
27     return;
28 }
29
30 inline void find(int cnt) {
31     int now=0;
32     int len=strlen(q[cnt]);
33     for(int i=0;i<len;++i) {
34         int x=q[cnt][i]-‘a‘+1;
35         if(!t[now][x]) break;
36         now=t[now][x];
37         if(sum[now]) ++ans,--sum[now];
38     }
39     return;
40 }
41
42 int hh() {
43     scanf("%d",&n);
44     for(int i=1;i<=n;++i) scanf("%s",s[i]),build(i);
45     for(int i=1;i<=n;++i) scanf("%s",q[i]),find(i);
46     printf("%d\n",ans);
47     return 0;
48 }
49
50 int sb=hh();
51 int main() {;}

题解

时间: 2024-12-06 17:44:52

51Nod 1526 分配 笔名的相关文章

1526 分配笔名(未完成存档)

#include <cstring> #include <cstdio> #define N 1000000 char real[N]; int f[N],pos,len,n,trie[N][26],exict[N],f[N],siz=1; inline void ins() { int len=strlen(real); for(int i=0;i<len;++i) { int id=real[i]-'a'; if(!trie[p][id]) trie[p][id]=++s

51Nod1526 分配笔名

分析 在trie树上贪心,将所有串加入trie树中,在深度较深的地方匹配会更优. 由于只需要知道最后的总质量,所以直接取每个点的子树中最大的匹配即可 复杂度\(O(\sum len)\) 加串的时候把路径上\(val\)加\(1\),查询串的时候把沿途\(val\)减\(1\),\(ans\)为减去的\(1\)的个数. 注意\(val\)为\(0\)的情况,如果后面有\(val\)为大于等于\(1\)的点,那么说明这次查询的串比以前查询的串贡献的答案更优,那么就直接加上后面那些\(val\)大于

51nod贪心算法教程

51nod确实是一个好oj,题目质量不错,wa了还放数据,学习算法来说挺好的,这次我做了几个水的贪心,虽然水,但是确实都很典型. 教程链接:http://www.51nod.com/tutorial/list.html 完美字符串 约翰认为字符串的完美度等于它里面所有字母的完美度之和.每个字母的完美度可以由你来分配,不同字母的完美度不同,分别对应一个1-26之间的整数.   约翰不在乎字母大小写.(也就是说字母F和f)的完美度相同.给定一个字符串,输出它的最大可能的完美度.例如:dad,你可以将

ZTE中兴利益分配金字塔

一. 金字塔式的利益分配结构:高层之蜜糖,骨干之砒霜中兴的利益分配文化就是高层38位元老利用中兴新控制中兴通信的管理决策,通过关联投资公司和关联实体公司抽取整个公司发展的利润回报(详见下图). 关联投资公司通过“中兴新”影响控制中兴通讯的管理决策.关联投资公司投资关联实体公司转移中兴通讯利润. 关联投资公司如何通过“中兴新”影响控制中兴通讯的管理决策?[中兴年报显示]中兴通讯第一大股东是中兴新,中兴新的背后股东为西安微电子所(34%股份)+航天广宇(17%)+中兴维先通(49%股份),而实际控制

51nod - 1363 - 最小公倍数之和 - 数论

https://www.51nod.com/Challenge/Problem.html#!#problemId=1363 求\(\sum\limits_{i=1}^{n}lcm(i,n)\) 先换成gcd: \(\sum\limits_{i=1}^{n}\frac{i*n}{gcd(i,n)}\) 显而易见,枚举g: $ n * \sum\limits_{g|n} \frac{1}{g} \sum\limits_{i=1}^{n} i*[gcd(i,n)==g] $ 提g,没有下整符号: $

【c/c++】内存分配大小

测试平台:linux 32位系统 用sizeof()运算符计算分配空间大小.单位:字节 1. 数组名与变量名的区别 int main() { char q[] = "hello"; cout << "q:" << sizeof(q) << endl; char *mq = q; cout << "mq:" << sizeof(mq) << endl; const char *

51nod 1201 整数划分(dp)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201 题解:显然是一道dp,不妨设dp[i][j]表示数字i分成j个一共有几种分法. 那么转移方程式为: dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] 表示将i - 1划分为j个数,然后j个数都+1 还是不重复,将i - 1划分为j - 1个数,然后j - 1个数都+1,再加上1这个数. 然后就是j的范围要知道1+2+

操作系统: 最佳适配算法和邻近适配算法的模拟实现(内存分配算法)

实现动态分区的分配算法. (1) 最佳适配算法:选择内存空闲块中最适合进程大小的块分配. (2) 邻近适配算法:从上一次分配的地址开始查找符合要求的块,所查找到的第一个满足要求的空闲块就分配给进程. 模拟添加进程的时候,假定内存是一块完整的空闲区,对于算法(1)来说,分配的时候遍历所有的空闲内存块,找出其中最适合的一块,注意此时内存分区的总块数可能已经发生了变化: 对于算法(2)来说,则需要从上次分配的内存块(使用变量记录即可)接着向下找到第一个满足条件的块即可,内存分区的总块可能也已经发生了变

JAVA中堆栈和内存分配

(一).栈.堆 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中.)3. 堆:存放所有new出来的对象.4. 静态域(属于方法区) :存放静态成员(static定义的)5. 常量池 (属于方法区):存放字符串常量和基本类型常量(public static final).6. 非RAM存储:硬盘等永久存储空间这里我们主要关心栈