Codeforces Round #508 (Div. 2)
阿新 • • 發佈:2018-12-18
A. Equality
因為是子序列,所以只要判斷前 個字母最多組成多少個子序列就行了
#include <iostream>
#include <climits>
#include <algorithm>
const int MAXN = 1e5 + 2;
std::string str;
int n, k, ans = INT_MAX;
int cnt[MAXN];
int main()
{
std::ios_base::sync_with_stdio(0);
std::cin >> n >> k >> str;
for (int i = 0; i < n; i++) {
cnt[str[i] - 'A']++;
}
for (int i = 0; i < k; i++) {
ans = std::min(ans, cnt[i]);
}
std::cout << ans * k << std::endl;
return 0;
}
B. Non-Coprime Partition
根據求和公式,前 項和為 ,而最後一項正是 ,兩者的 就是 ,然後再特判一下 和 的情況就行了
#include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
scanf("%d", &n);
if (n == 1) puts("No");
else if (n == 2) puts("No");
else {
puts("Yes");
printf("%d ", n - 1);
for (int i = 1; i < n; i++) {
printf("%d ", i);
}
printf("\n1 %d\n", n);
}
return 0;
}
C. Gambling
根據題意, 和 每次都要移除對手的一個數字或者拿走自己的一個數字,容易發現 和 每次都將移除或拿走當前最大的數字,所以直接模擬即可
#include <cstdio>
#include <algorithm>
const int MAXN = 100000 + 5;
int n;
long long ans;
int a[MAXN], b[MAXN];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
std::sort(a + 1, a + 1 + n);
std::sort(b + 1, b + 1 + n);
int na = n, nb = n;
char turn = 'a';
while (na > 0 && nb > 0) {
if (turn == 'a') {
if (a[na] > b[nb]) {
ans += a[na];
na--;
}
else nb--;
turn = 'b';
}
else {
if (b[nb] > a[na]) {
ans -= b[nb];
nb--;
}
else na--;
turn = 'a';
}
}
if (na > 0) {
if (turn == 'a') {
for (int i = na; i >= 1; i -= 2) {
ans += a[i];
}
}
else {
for (int i = na - 1; i >= 1; i -= 2) {
ans += a[i];
}
}
}
if (nb > 0) {
if (turn == 'a') {
for (int i = nb - 1; i >= 1; i -= 2) {
ans -= b[i];
}
}
else {
for (int i = nb; i >= 1; i -= 2) {
ans -= b[i];
}
}
}
printf("%lld\n", ans);
return 0;
}
D. Slime
設全部數字絕對值之和為 。 當全部都是正數的時候,讓一個數 不斷減去他旁邊的數到只剩 個數字,然後再用剩的那個數字 減去 ,這樣每個數相當於都加到了 中,唯獨 不但沒加還減去了,所以最後答案為 。 當全部都是負數的時候和上面同理,最後答案為 當有正有負的時候讓負數減去旁邊的正數直到只剩一個正數,然後那個正數再減掉所有的負數就好,所以答案為 。 所以要讓答案最大就是讓 最小。
#include <cstdio>
#include <algorithm>
#include <climits>
int n, max = INT_MIN, min = INT_MAX;
long long ans;
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
int tmp;
scanf("%d", &tmp);
max = std::max(max, tmp);
min = std::min(min, tmp);
ans += abs(tmp);
}
if (n == 1) {
printf("%d\n", max);
return 0;
}
else if (n == 2) {
printf("%d\n", abs(max - min));
return 0;
}
if (max < 0) {
printf("%lld\n", ans - 2 * abs(max));
}
else if (min > 0) {
printf("%lld\n", ans - 2 * abs(min));
}
else printf("%lld", ans);
return 0;
}