1993(963div2)
A. Question Marks
蒂姆正在做一个由
对于每道题,蒂姆都会把答案写在答题纸上。如果想不出答案,他会在该题上留下问号"?
他的答题纸上有
void solve() {
int n;cin >> n;
string s;cin >> s;
int a = count(s.begin(), s.end(), 'A');
int b = count(s.begin(), s.end(), 'B');
int c = count(s.begin(), s.end(), 'C');
int d = count(s.begin(), s.end(), 'D');
int ans = 4 * n;
ans -= max(n - a, 0);
ans -= max(n - b, 0);
ans -= max(n - c, 0);
ans -= max(n - d, 0);
cout << ans << '\n';
}
B. Parity and Sum
给定一个由
在一次操作中,你可以选取任意一对索引
- 如果
,则用 替换 ; - 否则,用
替换 。
求使数组中所有元素具有相同奇偶性所需的最少操作数。
易得每次尽量都用一次操作将所有的偶数给变为奇数,若需要两次操作的话,直接将最大的偶数与这个奇数来进行操作,后面每个数同样一定为 1 次,最多也只会超出一次操作。
需要特判全为偶数的情况
#define int long long
void solve() {
int n;cin >> n;
vector<int> a(n + 1);
for (int i = 1;i <= n;i++)cin >> a[i];
vector<int> even;
int odd = 0;
for (int i = 1;i <= n;i++) {
if (a[i] % 2 == 0)even.push_back(a[i]);
else odd = max(odd, a[i]);
}
if (!odd) {
cout << "0\n";return;
}
sort(even.begin(), even.end());
int cnt = 0, ok = 1;
for (auto x : even) {
if (odd < x) {
ok = 0;
}
odd += x;
}
cout << even.size() + !ok << '\n';
}
C. Light Switches
有一栋公寓由
为了控制这些房间的灯光,公寓的主人决定在房间里安装芯片,这样每个房间正好有一个芯片,芯片安装在不同的时间。具体来说,这些时间由数组
芯片一经安装,每隔
公寓里所有房间最早亮灯的时刻是什么时候?
易得答案总数大于等于最晚开灯的时间的。且不会很大,求这些区间的交集的最小值
#define int long long
void solve() {
int n, k;cin >> n >> k;
vector<int>a(n + 1);
for (int i = 1;i <= n;i++)cin >> a[i];
sort(a.begin() + 1, a.end());
for (int i = 1;i < n;i++) {
if (a[i] + k < a[n]) {
int b = (a[n] - a[i]) / k;
if (b & 1)b++;
a[i] += b * k;
}
}
int l = 1, r = 1e18;
for (int i = 1;i <= n;i++) {
l = max(l, a[i]);
r = min(r, a[i] + k);
}
if (l >= r) {
cout << "-1\n";return;
}
cout << l << '\n';
}
D. Med-imize
给定两个正整数
在一次操作中,可以选择
当
Solution
EDU: 二分+DP
注意:我的二分写法需要将 r 的范围多拓展一点,不然可能会错
366 之后补
void solve() {
int n, k;cin >> n >> k;
vector<int> a(n), b(n), dp(n);
for (int i = 0;i < n;i++)cin >> a[i];
int l = 0, r = 2e9;
while (l < r) {
int mid = l + r >> 1;
for (int i = 0;i < n;i++) {
if (a[i] >= mid) {
b[i] = 1;
} else {
b[i] = -1;
}
}
dp[0] = b[0];
for (int i = 1;i < n;i++) {
if (i % k == 0) {
dp[i] = max(dp[i - k], b[i]);
} else {
dp[i] = dp[i - 1] + b[i];
if (i > k) {
dp[i] = max(dp[i], dp[i - k]);
}
}
}
if (dp[n - 1] <= 0)r = mid;
else l = mid + 1;
}
cout << l - 1 << '\n';
}