Uva 11488 Hyper Prefix Sets 字典树

该博客主要介绍了如何使用字典树数据结构解决Uva 11488题目的挑战,即寻找字符串集合中公共前缀长度之和最长的子集。在构建字典树后,通过深度优先遍历计算每个节点的贡献值,并在回溯过程中释放内存以避免内存溢出。
摘要由CSDN通过智能技术生成
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


题意:给出一个字符串的集合,找出一个子集,使得子集中所有的字符串的公共前缀的长度之和最长

数据结构:字典树

设计:每个节点存储这个节点被插入的次数cnt,建好树之后,进行一次深度优先遍历,对于每一个i节点,用它的深度乘以cnt,得到的值就是以这个节点为结尾的公共前缀长度之和。找出最大的值,别忘了回溯的时候释放内存,不然内存会boom掉大笑

#include <iostream>
#include <stdio.h>
#define MAX 210
using namespace std;

struct trie
{
    int cnt;
    trie *next[2];
};
trie *root=new trie;
int n,res;
char str[MAX];

void insert_trie()
{
    trie *p,*newnode;
    p=root;
    for(int i=0; str[i]!='\0'; i++)
    {
        if(p->next[str[i]-'0']==NULL)
        {
            newnode=new trie;
            newnode->cnt=1;
            newnode->next[0]=newnode->next[1]=NULL;
            p->next[str[i]-'0']=newnode;
            p=newnode;
        }
        else
        {
            p->next[str[i]-'0']->cnt++;
            p=p->next[str[i]-'0'];
        }
    }

}

void dfs(trie *p,int cur)
{
    for(int i=0; i<2; i++)
    {
        if(p->next[i]!=NULL)
        {
            int tmp=cur*p->next[i]->cnt;
            if(res<tmp)
                res=tmp;
			dfs(p->next[i],cur+1);
			delete(p->next[i]);
			p->next[i]=NULL;
        }
    }
}



int main()
{
    int t,i;
    scanf("%d",&t);
    while(t--)
    {
        res=0;
        for(i=0;i<2;i++)
			root->next[i]=NULL;
        scanf("%d",&n);
        for(i=0; i<n; i++)
		{
			 scanf("%s",str);
			 insert_trie();
		}
		//printf("finish insert\n");
		dfs(root,1);
		printf("%d\n",res);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值