Hyper Prefix Sets UVA - 11488 字典树裸题

Prefix goodness of a set string is length of longest common prefix*number of strings in the set. For
example the prefix goodness of the set {000,001,0011} is 6.You are given a set of binary strings. Find
the maximum prefix goodness among all possible subsets of these binary strings.
Input
First line of the input contains T (≤ 20) the number of test cases. Each of the test cases start with n
(≤ 50000) the number of strings. Each of the next n lines contains a string containing only ‘0’ and ‘1’.
Maximum length of each of these string is 200.
Output
For each test case output the maximum prefix goodness among all possible subsets of n binary strings.
Sample Input
4
4
0000
0001
10101
010
2
01010010101010101010
11010010101010101010
3
010101010101000010001010
010101010101000010001000
010101010101000010001010
5
01010101010100001010010010100101
01010101010100001010011010101010
00001010101010110101
0001010101011010101
00010101010101001
Sample Output
6
20
66

44

题意:找出字符串集合的一个前缀,使得前缀长度*出现次数的值为最大。

方法:用字典树处理字符串,同时在树的节点处记录前缀出现的次数以及长度,最后求出最大值。

字典树的用法可以看这位大佬的博客,讲的很简单明了详细。

https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html

顺便自己复习一下字典树。字典树的存储方法,用二维数组模拟树,trie[i][j]=k,代表节点号为i的第j个子节点节点号为k.我们在树上存储字符串时,在用边来代表字母,同时在边的末尾记录字符串的一些值。比如出现次数,字符串长度,以及单词结束标志等。

代码:

#include<bits/stdc++.h>
using namespace std;
int trie[10000010][2];
int sum[10000010];
int deep[10000010];
int tot;
void Insert(char *s)
{
    int rt=0;
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int now=s[i]-'0';
        if(!trie[rt][now]){
            trie[rt][now]=++tot;
            deep[tot]=i+1;
        }
        //deep[trie[rt][now]]=deep[rt]+1;
        rt=trie[rt][now];
        sum[rt]++;
    }
}
char s[300];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        tot=0;
        memset(trie,0,sizeof(trie));
        memset(sum,0,sizeof(sum));
        memset(deep,0,sizeof(deep));
        while(n--)
        {
            scanf("%s",s);
            Insert(s);
        }
        int ans=0;
        for(int i=0;i<=tot;i++)
            ans=max(ans,sum[i]*deep[i]);
        printf("%d\n",ans);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值