• (trie)BUAAOJ 371


    题目链接

    分别对名字和绰号建立2个trie树,其中记录树每个结点经过过多少次。

    每个字符串在trie树中的路径都是固定的,故可以同时遍历两个树(某树不存在某个结点就停止这一侧的遍历),不妨设某一结点 名字树有x次经历,绰号树有y次经历。(不妨设x<=y),则任取y个绰号中的x个与这x个名字任意匹配,都会产生x个匹配,故加上x(实际操作中就是min(x,y))。(倒序考虑最终匹配方式,前面的过程任意匹配即可)一直重复该过程,所得答案即为总相似度最大的方式。

      1 #include <iostream>
      2 #include <string>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <queue>
      8 #include <set>
      9 #include <map>
     10 #include <list>
     11 #include <vector>
     12 #include <stack>
     13 #define mp make_pair
     14 #define MIN(a,b) (a>b?b:a)
     15 #define rank rankk
     16 //#define MAX(a,b) (a>b?a:b)
     17 typedef long long ll;
     18 typedef unsigned long long ull;
     19 const int MAX=1e6+5;
     20 const int INF=1e9+5;
     21 const int B=1024;//桶的大小
     22 const double M=4e18;
     23 const int MAX_NODE=510000;
     24 const int sigma_size=26;
     25 using namespace std;
     26 //const int MOD=1e9+7;
     27 const int MOD=20071027;
     28 typedef pair<int,int> pii;
     29 const double eps=0.000000001;
     30 
     31 struct Trie
     32 {
     33     int ch[MAX_NODE][sigma_size];//点数、“字母”数
     34     int val[MAX_NODE];
     35     int num;//结点总数
     36     Trie(){num=1;memset(val,0,sizeof(val));memset(ch,0,sizeof(ch));}//初始时仅有根节点
     37     void clear() {num = 1;memset(ch, 0, sizeof(ch));memset(val,0,sizeof(val)); }
     38     int idx(char c)//返回对应字符的编号
     39     {
     40         return c-'a';
     41     }
     42     /*
     43         插入字符串s,附加信息为v。注意v必须非0,因为0代表:本结点不是单词结点
     44     */
     45     void insert(const char *s,int v)
     46     {
     47         int u=0,len=strlen(s);
     48         for(int i=0;i<len;i++)
     49         {
     50 //            ++val[u];
     51             int c=idx(s[i]);
     52             if(!ch[u][c])//结点不存在
     53             {
     54                 memset(ch[num],0,sizeof(ch[num]));
     55 //                val[num]=0;//中间节点的附加信息为0
     56 //                ++val[num];
     57                 ch[u][c]=num++;//新建结点
     58             }
     59             u=ch[u][c];//往下走
     60             ++val[u];
     61         }
     62 //        ++val[u];
     63 //        val[u]=v;//字符串的最后一个字符的附加信息为v
     64     }
     65     /*
     66      查询字符串的“附加信息”
     67      查询过程中间中断返回0
     68     */
     69     int check(char *s)
     70     {
     71         int u=0,len=strlen(s);
     72         for(int i=0;i<len;i++)
     73         {
     74             int c=idx(s[i]);
     75             if(!ch[u][c])
     76                 return 0;
     77             u=ch[u][c];
     78         }
     79         return val[u];
     80     }
     81     /*
     82     找字符串s的长度不超过len的前缀
     83     */
     84     void find_prefixes(const char *s,int len,vector <int> &ans)
     85     {
     86         int u=0;
     87         for(int i=0;i<len;i++)
     88         {
     89             if(s[i]=='')
     90                 break;
     91             int c=idx(s[i]);
     92             if(!ch[u][c])
     93                 break;
     94             u=ch[u][c];
     95             if(val[u]!=0)//过程中所有找到的全都push进去
     96                 ans.push_back(val[u]);
     97         }
     98     }
     99 };
    100 Trie t1,t2;
    101 int n;
    102 char tem[MAX];
    103 ll an;
    104 void dfs(int lo1,int lo2)
    105 {
    106     an+=min(t1.val[lo1],t2.val[lo2]);
    107     for(int i=0;i<26;i++)
    108     {
    109         if(t1.ch[lo1][i]&&t2.ch[lo2][i])
    110             dfs(t1.ch[lo1][i],t2.ch[lo2][i]);
    111     }
    112 }
    113 int main()
    114 {
    115     while(~scanf("%d",&n))
    116     {
    117         t1.clear();t2.clear();
    118         for(int i=0;i<n;i++)
    119         {
    120             scanf("%s",tem);
    121             t1.insert(tem,1);
    122         }
    123         for(int i=0;i<n;i++)
    124         {
    125             scanf("%s",tem);
    126             t2.insert(tem,1);
    127         }
    128         an=0;
    129         dfs(0,0);
    130         printf("%lld
    ",an);
    131     }
    132 }
  • 相关阅读:
    软件测试
    python集合
    python基础(一)
    python布尔(空值)
    2013-12-15
    卸载IE9,IE10,IE11
    <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>
    Log4j.properties配置详解
    WinCVS提交时出现错误 cvs server: C:/WINDOWS/TEMP/cvs**.tmp: No such file or directory 的解决方案
    Available Memory Is Low
  • 原文地址:https://www.cnblogs.com/quintessence/p/6897872.html
Copyright © 2020-2023  润新知