Codeforces Round #734 (Div. 3)-C. Interesting Story-题解

128 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

@TOC

Codeforces Round #734 (Div. 3)-C. Interesting Story

传送门 Time Limit: 4 seconds Memory Limit: 256 megabytes

Problem Description

Stephen Queen wants to write a story. He is a very unusual writer, he uses only letters 'a', 'b', 'c', 'd' and 'e'!

To compose a story, Stephen wrote out nn words consisting of the first 55 lowercase letters of the Latin alphabet. He wants to select the maximum number of words to make an interesting story.

Let a story be a sequence of words that are not necessarily different. A story is called interesting if there exists a letter which occurs among all words of the story more times than all other letters together.

For example, the story consisting of three words "bac", "aaada", "e" is interesting (the letter 'a' occurs 55 times, all other letters occur 44 times in total). But the story consisting of two words "aba", "abcde" is not (no such letter that it occurs more than all other letters in total).

You are given a sequence of nn words consisting of letters 'a', 'b', 'c', 'd' and 'e'. Your task is to choose the maximum number of them to make an interesting story. If there's no way to make a non-empty story, output 00.

Input

The first line contains one integer tt (1t50001 \le t \le 5000) — the number of test cases. Then tt test cases follow.

The first line of each test case contains one integer nn (1n21051 \le n \le 2 \cdot 10^5) — the number of the words in the sequence. Then nn lines follow, each of them contains a word — a non-empty string consisting of lowercase letters of the Latin alphabet. The words in the sequence may be non-distinct (i. e. duplicates are allowed). Only the letters 'a', 'b', 'c', 'd' and 'e' may occur in the words.

It is guaranteed that the sum of nn over all test cases doesn't exceed 21052 \cdot 10^5; the sum of the lengths of all words over all test cases doesn't exceed 41054 \cdot 10^5.

Output

For each test case, output the maximum number of words that compose an interesting story. Print 0 if there's no way to make a non-empty interesting story.

Sample Input

6
3
bac
aaada
e
3
aba
abcde
aba
2
baba
baba
4
ab
ab
c
bc
5
cbdca
d
a
d
e
3
b
c
ca

Sample Onput

3
2
0
2
3
2

Note

In the first test case of the example, all 33 words can be used to make an interesting story. The interesting story is "bac aaada e".

In the second test case of the example, the 11-st and the 33-rd words can be used to make an interesting story. The interesting story is "aba aba". Stephen can't use all three words at the same time.

In the third test case of the example, Stephen can't make a non-empty interesting story. So the answer is 00.

In the fourth test case of the example, Stephen can use the 33-rd and the 44-th words to make an interesting story. The interesting story is "c bc".


题目大意

一种有趣的文章,只有a~e这5种字母组成。 给你一些可选单词,让你选一些单词组成文章,需要满足其中某种字母的出现次数>所有其他字母的出现次数的总和其中某种字母的出现次数>所有其他字母的出现次数的总和 问你最多能选几个单词。

解题思路

就5种字母,我们可以假设其中某个字母出现次数有压倒性优势,对于这种字母,看每个单词的贡献程度

其中,一个单字母在某个单词中的贡献程度是指这个单词中这个字母出现的次数减去其他所有字母出现的次数。

按贡献程度从大到小进行排序,累加直到总贡献程度不能再大于0为止。

比如要看字母a的贡献程度:

单词aaaabc中a出现了4次其他出现了2次,a在此单词中的贡献程度就行4-2=2。即为a比其他所有字母总共多出现了2次


AC代码

/*
 * @Author: LetMeFly
 * @Date: 2021-07-23 23:29:26
 * @LastEditors: LetMeFly
 * @LastEditTime: 2021-07-24 22:31:34
 */ //@LastEditTime: 2021-07-23 23:43:07
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
int a[26][200010];
char s[400010];
void debug(int a[], int n) // 用来中途debug的函数,不用管(作用是打印数组a。
{
    for(int i=0;i<n;i++)
    {
        cout<<a[i]<<' ';
    }
    puts("");
}
int main()
{
    int N;
    cin>>N;
    while(N--) // N组测试样例
    {
        int n;
        cd(n); // scanf("%d",&n);
        for(int i=0;i<26;i++) // 对于每一种字母(其实到i<5即可,因只有字母a~e)
            for(int j=0;j<n;j++)
                a[i][j]=0; // 初始化为0
        for(int i=0;i<n;i++)
        {
            scanf("%s",s);
            int l=strlen(s);
            int temp[26]={0}; // 这个单词的每种字母的出现次数
            for(int j=0;j<l;j++) // 遍历这个单词的每一个字母
            {
                temp[s[j]-'a']++; // 出现次数++
            }
            for(int j=0;j<26;j++) // 对于每一个字母,计算出它的贡献度
            {
                a[j][i]=2*temp[j]-l; // a[j][i]-(l-a[j][i])
            }
        }
        int M=0; // 最多选取的单词数量
        for(int i=0;i<26;i++) // 假设以这个字母作为压倒性优势
        {
            sort(a[i],a[i]+n,greater<int>()); // 对这种字母的n个单词的贡献度全部排序
            // debug(a[i], n);//**************
            int s=0; // s个单词
            int sum=0; // 总贡献度
            for(int j=0;j<n;j++) // 遍历每个单词
            {
                if(sum+a[i][j]>0) // 如果累加上去后贡献度还是正的,说明a的总出现次数-其他字母的总出现次数>0
                {
                    sum+=a[i][j];
                    s++;
                }
                else // 否则就退出
                {
                    break;
                }                
            }
            M=max(M,s); // 更新最大值M
        }
        printf("%d\n",M); // 输出
    }
    return 0;
}

同步发文于我的CSDN,原创不易,转载请附上原文链接哦~
Tisfy:letmefly.blog.csdn.net/article/det…