题目链接: Interesting Story
大致题意
给出n个仅包含小写字母’a’ ~ 'e’的字符串.
要求: 选择尽可能多的字符串, 并且满足: 在选择的字符串中, ‘a’ ~ 'e’中的某一个字符比其他所有字符加和还要多. (相当于把所有选择的字符串组成了一个新串, 要求某个字符数量多于其它所有的.)
解题思路
贪心
我们设target
字符为最多的那个字符, other
为其它所有的字符.
不妨枚举target=‘a’~'e’的所有情况: 由于我们希望选择尽可能多的字符串, 因此我们可以贪心选择target - other 的数目
大的.
感觉这个题重点是代码实现吧. 贪心的思路应该不是很难.
我这里使用lambda表达式进行的排序.
AC代码
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 2E5 + 10;
struct node {
string s;
int c[5]; // 记录a~e每个字符的个数
void init() {
for (int i = 0; i < 5; ++i) c[i] = 0;
for (auto& op : s) c[op - 'a']++;
}
}a[N];
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t; cin >> t;
while (t--) {
int n; cin >> n;
rep(i, n) {
cin >> a[i].s;
a[i].init();
}
int res = 0;
for (int k = 0; k < 5; ++k) {
sort(a + 1, a + 1 + n, [&k](const node& x, const node& y) {
int ox = x.s.size() - x.c[k]; //其它的字符个数
int oy = y.s.size() - y.c[k];
int cx = x.c[k] - ox, cy = y.c[k] - oy; //当前字符比其它字符多多少.
return cx > cy;
});
int now = 0, target = 0, other = 0; //已选单词个数, 当前字符个数, 其它字符个数
rep(i, n) {
int nt = target + a[i].c[k]; // next_target
int no = other + a[i].s.size() - a[i].c[k]; // next_other
if (nt > no) {
now++;
target = nt, other = no;
}
else break;
}
res = max(res, now);
}
cout << res << endl;
}
return 0;
}