Educational Codeforces Round 142 (Rated for Div. 2)【A - D】

中间两题罚时太多了。

比赛链接:https://codeforces.com/contest/1792

A. GamingForces

题解

贪心,将 1 都用第一种操作删除,其他数都用第二种操作。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <bits/stdc++.h>
using namespace std;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);

int t;
cin >> t;

while (t--) {
int n;
cin >> n;

int one = 0, other = 0;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
(x == 1 ? one : other) += 1;
}
cout << (one + 1) / 2 + other << "\n";
}

return 0;
}

B. Stand-up Comedian

题解

执行第 2 或第 3 种操作总和不变,所以可以先执行第 1 种操作,然后重复执行第 2、3 种操作,直至一种为 0,然后讨论最小情绪值和余下两种操作的大小关系就可以了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <bits/stdc++.h>
using namespace std;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);

int t;
cin >> t;

while (t--) {
int a, b, c, d;
cin >> a >> b >> c >> d;

int ans = 0, min_mood = 0;

ans += a;
min_mood += a;

auto op = [](int& x, int& y) {
int mi = min(x, y);
x -= mi, y-= mi;
return mi;
};

if (min_mood > 0) {
if (b > c) {
swap(b, c);
}
ans += 2 * op(b, c);
}

ans += op(min_mood, c);

ans += op(min_mood, d);

cout << ans + (max({b, c, d}) > 0) << "\n";
}

return 0;
}

C. Min Max Sort

题解

操作次数最多为 n2\lfloor \frac{n}{2} \rfloor ,从中间值找有多少数对的相对位置满足排序后的关系,从总操作次数中减去这些可以省下的操作次数即可。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <bits/stdc++.h>
using namespace std;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);

int t;
cin >> t;

while (t--) {
int n;
cin >> n;

vector<int> a(n), pos(n + 1);
for (int i = 0; i < n; i++) {
cin >> a[i];
pos[a[i]] = i;
}

int ans = n / 2;

int l, r;
int val_l, val_r;

if (n & 1) {
l = r = find(a.begin(), a.end(), (n + 1) / 2) - a.begin();
val_l = (n + 1) / 2 - 1, val_r = (n + 1) / 2 + 1;
} else {
l = find(a.begin(), a.end(), n / 2) - a.begin();
r = find(a.begin(), a.end(), n / 2 + 1) - a.begin();
val_l = n / 2 - 1, val_r = n / 2 + 2;
}

if (l <= r) {
ans -= (n % 2 == 0);
while (pos[val_l] < l and pos[val_r] > r) {
l = pos[val_l], r = pos[val_r];
val_l -= 1, val_r += 1;
ans -= 1;
}
}

cout << ans << "\n";
}

return 0;
}

D. Fixed Prefix Permutations

题解

将值的不连续分布转化为位置的连续分布后进行二分。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <bits/stdc++.h>
using namespace std;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);

int t;
cin >> t;

while (t--) {
int n, m;
cin >> n >> m;

vector a(n, vector<int>(m)), pos(a);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> a[i][j];
--a[i][j];
pos[i][a[i][j]] = j;
}
}

sort(pos.begin(), pos.end());

for (int i = 0; i < n; i++) {
int l = 0, r = m;
auto ok = [&](int mid) {
vector<int> need(m, -1);
for (int j = 0; j < mid; j++) {
need[j] = a[i][j];
}
auto it = lower_bound(pos.begin(), pos.end(), need);
if (it == pos.end()) {
return false;
}
for (int j = 0; j < mid; j++) {
if (need[j] != (*it)[j]) {
return false;
}
}
return true;
};
while (l < r) {
int mid = (l + r + 1) / 2;
if (ok(mid)) {
l = mid;
} else {
r = mid - 1;
}
}
cout << l << " \n"[i == n - 1];
}
}

return 0;
}

Educational Codeforces Round 142 (Rated for Div. 2)【A - D】

https://www.kanoon.cn/2023/01/25/CF-1792/

作者

Kanoon

发布于

2023-01-25

更新于

2023-01-25

许可协议

评论