J - 方师傅的01串

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

方师傅过生日啦,于是蟹毛买了N01串,想送给方师傅。

但是蟹毛觉得这些01串不够美,于是他想从中选出一些送给方师傅。

蟹毛对于p01串的美值定义为: 这些01串的最长公共前缀的长度×p

所以蟹毛想从N01串中选出一些,使得这些01串的美值最高。

请告诉蟹毛最好的美值是多少。

Input

输入第1行包含1个整数N,表示蟹毛买到的01串的个数。

接下来N行,每行包含101串。

N50000,每个01串长度不超过200

Output

输出包含1个整数,代表最高的美值。

Sample input and output

Sample InputSample Output
4
0000
0001
10101
010
6
5
01010101010100001010010010100101
01010101010100001010011010101010
00001010101010110101
0001010101011010101
00010101010101001
44

 题意求多个01串的最长公共前缀的长度×p的最大值

无比简单的trie,简单到可以直接用二叉树模拟,就是直接用数组模拟,

N的子节点是2*n和2*n+1,N的父节点是N/2;

左节点是0,右节点是1,直接建树加一个dfs搜索一下整棵树就OK啦

 

#include <iostream>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
struct node
{
    struct node* left;
    struct node* right;
    int data;
};

int maxn=-1;

using namespace std;

void build(char* z,node* p)
{
    node* pi;
    if (z[0]=='\0') return;
    if (z[0]=='1') {
        if (p->left==NULL){
            pi=(node*)malloc(sizeof(node));
            pi->left=NULL;
            pi->right=NULL;
            pi->data=0;
            p->left=pi;
        }
        (p->left)->data++;
        build(z+1,p->left);
        return;
    }
    if (z[0]=='0'){
        if (p->right==NULL){
            pi=(node*)malloc(sizeof(node));
            pi->left=NULL;
            pi->right=NULL;
            pi->data=0;
            p->right=pi;
        }
        (p->right)->data++;
        build(z+1,p->right);
        return;
    }
}
void suan(node* p,int j)
{
    if (p->data*j>maxn) maxn=p->data*j;
    if (p->left!=NULL) suan((p->left),j+1);
    if (p->right!=NULL) suan((p->right),j+1);
}
int main()
{
    int n;
    char z[202]={'\0'};
    scanf("%d",&n);
    node *head;
    head=(node*)malloc(sizeof(node));
    head->left=NULL;
    head->right=NULL;
    head->data=0;
    while (n--){
        scanf("%s",z);
        build(z,head);
    }
    suan(head,0);
    printf("%d\n",maxn);
    return 0;
}