题意:给你一个01串集合 定义P(S)为S集合字符串的公共前缀长度与S中字符串个数的乘积 要你从中选一个S 使得P(S)最大
思路:又是裸的字典树。。。感觉做水题真爽。。。十分钟一个。。。用字典树存下每个字符串的信息(重复次数和深度)边存入边更新即可
#include <cstdio>
#include <cstring>
using namespace std;
#define REP( i, a, b ) for( int i = a; i < b; i++ )
const int maxn = 50000 + 10;
struct Trie{
int va, deep;
Trie *next[2];
Trie(int va = 0, int deep = 0) : va(va), deep(deep) { next[0] = next[1] = NULL; }
};
int n;
int Max(int a, int b){ return a > b ? a : b; }
int CreatTrie(Trie *root, char *str){
int ans = 0;
int len = strlen(str);
Trie *p = root, *q;
REP(i, 0, len){
int id = str[i] - '0';
if(p -> next[id] == NULL){
q = new Trie(1, i + 1);
p -> next[id] = q;
ans = Max(ans, p -> next[id] -> va * p -> next[id] -> deep);
p = p -> next[id];
}
else{
p -> next[id] -> va ++;
ans = Max(ans, p -> next[id] -> va * p -> next[id] -> deep);
p = p -> next[id];
}
}
return ans;
}
void DelTrie(Trie *root){
if(root == NULL) return;
DelTrie(root -> next[0]);
DelTrie(root -> next[1]);
delete[] root;
}
void solve(){
int ans = 0;
char str[210];
Trie *root = new Trie(0, 0);
scanf("%d", &n);
REP(i, 0, n){
scanf("%s", str);
ans = Max(CreatTrie(root, str), ans);
}
printf("%d\n", ans);
DelTrie(root);
}
int main()
{
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--) solve();
return 0;
}