T1:最大数量

本题难度简单,考察二维数组计数,注意枚举小时和分钟从 0 开始。

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int f[30][70]; // f[i][j] 记录 i 时 j 分这个时刻进入商场的人数
int main() {
int n;
cin >> n;
rep(i, n) {
int h, m;
cin >> h >> m;
f[h][m]++;
}
int maxn = 0, max_h = -1, max_m = -1;
rep(i, 24)rep(j, 60) {
if (f[i][j] > maxn) {
maxn = f[i][j];
max_h = i;
max_m = j;
}
}
cout << max_h << ' ' << max_m << '\n';
cout << maxn << '\n';
return 0;
}

T2:字符串拆分

本题难度中等,考察字符串基础、数组计数和前缀和技巧。枚举分界点 i,计算分界点 i 左右两边各出现不同字符的数量,这里可以使用数组计数+前缀和优化。

当分界点从 i1 变为 i 时:
左子串多了一个字符 si,右子串少了一个字符 si
若左子串加入 si 之后且 si 的个数为 1,那么左子串的不同字符的个数 ++
若右子串去掉 si 之后且 si 的个数为 0,那么右子串的不同字符的个数 --

初始时,左子串为空,右子串为 s0sn1

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
void solve() {
int n;
string s;
cin >> n >> s;
int ans = 0;
int cntl = 0, cntr = 0;
vector<int> pre(130), suf(130);
rep(i, n) if (++suf[s[i]] == 1) cntr++;
rep(i, n-1) {
if (++pre[s[i]] == 1) cntl++;
if (--suf[s[i]] == 0) cntr--;
ans = max(ans, cntl+cntr);
}
cout << ans << '\n';
}
int main() {
int t;
cin >> t;
while (t--) solve();
return 0;
}

T3:喵星学院

本题难度中等,考察排序和桶以及拿部分分的能力,可以发现报名费一定是某个喵星人所愿意支付的钱,所以从小到大枚举每一个喵星人愿意支付的钱,不断更新答案即可。

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
int n;
cin >> n;
vector<int> w(n);
rep(i, n) cin >> w[i];
sort(w.begin(), w.end());
ll ans = 0, tot = 0;
rep(i, n) {
if (ll(n-i)*w[i] > tot) {
tot = ll(n-i)*w[i];
ans = w[i];
}
}
cout << tot << ' ' << ans << '\n';
return 0;
}