• 刷题总结——分配笔名(51nod1526 trie树)


    题目:

    班里有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


    题解:

      这道题一来没有注意到一一对应关系直接上trie树暴力匹配挂成0······

      下次一定要仔细读题了···其实保证两次笔名的一一对应关系的方法是很简单的··具体看代码

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<ctime>
    using namespace std;
    const int N=800005;
    int n,son[N][26],len,tot,a[N],b[N];
    char s[N];
    inline void build(int a[])
    {
      int po=0;
      for(int i=1;i<=len;i++)
      {
        if(!son[po][s[i]-'a'])  son[po][s[i]-'a']=++tot;
        po=son[po][s[i]-'a'];a[po]++;
      }
    }
    int main()
    {
      //freopen("a.in","r",stdin);
      scanf("%d",&n);
      for(int i=1;i<=n;i++)
      {
        scanf("%s",s+1);len=strlen(s+1);build(a);
      }
      for(int i=1;i<=n;i++)
      {
        scanf("%s",s+1);len=strlen(s+1);build(b);
      }
      int ans=0;
      for(int i=1;i<=tot;i++)  ans+=min(a[i],b[i]);
      cout<<ans<<endl;
      return 0;
    }



  • 相关阅读:
    HTTP响应状态码
    跨域
    第一章-极限与函数
    离群点检测
    关联规则(初识)
    python分类预测模型的特点
    分类预测算法评价(初识)
    人工神经网络(初识)
    决策树(初识)
    挖掘建模
  • 原文地址:https://www.cnblogs.com/AseanA/p/7718604.html
Copyright © 2020-2023  润新知