目录
题目链接
https://codeforces.com/contest/1427
A. Avoiding Zero
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int a[N], b[N], n;
void solve() {
cin >> n;
int s1 = 0, s2 = 0;// 负数和 正数和
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] < 0) s1 += a[i];
else s2 += a[i];
}
sort(a + 1, a + 1 + n);
s1 = abs(s1);
if (s1 > s2) { // 负数多
for (int i = 1; i <= n; i++) {
b[i] = a[i];
}
} else {
for (int i = 1; i <= n; i++) {
b[i] = a[n - i + 1];
}
}
int sum = 0;
int f = 0;
for (int i = 1; i <= n; i++) {
sum += b[i];
if (!sum) {
f = 1;
break;
}
}
if (f) {
cout << "NO" << endl;
} else {
cout << "YES" << endl;
for (int i = 1; i <= n; i++) {
cout << b[i] << " \n"[i == n];
}
}
}
void Run() {
int T;
cin >> T;
for (int cs = 1; cs <= T; cs++) {
solve();
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
Run();
return 0;
}
B. Chess Cheater · 贪心
对于每一个连续的W,发现将L修改成W后,只对第一个W的得分有影响,即可能从得分1变成得分2
对于每一个连续的区间L,若存在:左边至少有一个W,右边无W
.
.
.
W
L
.
.
.
L
...WL...L
...WL...L
显然优先从区间左端点开始往右修改,修改不会对原来的W造成影响,假设这一段连续的区间有x个L,则修改这一段区间会增加
2
x
2x
2x 分,
若存在:左边无W,右边至少有一个W
L
.
.
.
L
W
.
.
.
L...LW...
L...LW...
显然优先从区间的右端点开始往左填充,修改后会对右边第1个W造成影响,修改区间会增加
2
x
2x
2x 分(相当于将W的第一个移到了能修改的L的最前面)
若存在:左右边均至少有一个W
.
.
.
W
L
.
.
.
L
W
.
.
.
...WL...LW...
...WL...LW...
当剩余修改次数足够时,修改区间会增加
2
x
+
1
2x+1
2x+1 分;当修改区间不足时,就是上面两种情况
特判 若存在:左右边都无W
L
.
.
.
L
L...L
L...L
剩余次数不管是否足够,都必须存在一个1分的W,修改区间会增加
2
x
−
1
2x-1
2x−1 分
优先贪2x+1的部分,然后是2x,最后是2x-1
#include <bits/stdc++.h>
using namespace std;
string s;
int n, m, k;
struct L {
int x, b;
bool operator<(const L o) const {
if (b == o.b) return x < o.x;
return b > o.b;
}
};
vector<L> v;
void solve() {
cin >> n >> k;
cin >> s;
s = " " + s;
v.clear();
int lastW = -1;
int res = 0;
for (int i = 1; i <= n; i++) {
if (s[i] == 'L') {
int cnt = 0, j = i;
while (j <= n && s[j] == 'L') j++, cnt++;
i = j - 1;
if (lastW == -1 && j == n + 1) {//左无 右无
v.push_back({cnt, -1});
} else if (lastW == -1 || j == n + 1) {// 无左 右有 || 有左 无右
v.push_back({cnt, 0});
} else v.push_back({cnt, 1});
} else {
if (lastW == i - 1) res += 2;
else res++;
lastW = i;
}
}
n = v.size();
sort(v.begin(), v.end());
int sum = 0;
for (int i = 0; i < n; i++) {
if (sum + v[i].x <= k) {
sum += v[i].x;
res += v[i].x * 2 + v[i].b;
} else {
res += (k - sum) * 2 + (v[i].b == -1 && k - sum > 0 ? -1 : 0);
break;
}
}
cout << res << endl;
}
void Run() {
int T;
cin >> T;
for (int cs = 1; cs <= T; cs++) {
solve();
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
Run();
return 0;
}