Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解
Posted 繁凡さん
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解相关的知识,希望对你有一定的参考价值。
整理的算法模板合集: ACM模板
实际上是一个全新的精炼模板整合计划
Educational Codeforces Round 114 (Rated for Div. 2)
比赛链接:https://codeforces.com/contest/1574/
前四题过于简单()
后两题有点要命()
A. Regular Bracket Sequences
Problem
Solution
只要求输出 n n n 对合法括号,我们移动一下其中一个右括号即可。
Code
// Problem: A. Regular Bracket Sequences
// Contest: Codeforces - Educational Codeforces Round 114 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1574/problem/A
// Memory Limit: 512 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e5 + 6, INF = 0x3f3f3f3f;
int n, m, s, t;
ll ans;
int a[maxn];
void solve()
{
cin >> n;
for(int i = 1; i <= n; ++ i) {
int cnt1 = n, cnt2 = n;
for (int j = 1; j <= 2 * n; ++ j) {
if(j == i + 1) {
cnt2 -- ;
putchar(')');
}
else {
if(cnt1) {
cnt1 -- ;
putchar('(');
}
else if(cnt2) {
cnt2 -- ;
putchar(')');
}
}
}
puts("");
}
}
int main()
{
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
B. Combinatorics Homework
Problem
Solution
设 s u m = a + b + c sum=a+b+c sum=a+b+c
最多的对数显然就是按照顺序放置,一共有 r = s u m − 3 r = sum-3 r=sum−3 对。
最少的对数,我们使用数量较小的两个字母 h a c k = s u m − max { a , b , c } hack=sum-\\max\\{a,b,c\\} hack=sum−max{a,b,c},去将数量最多的字母隔开,一共可以隔开 2 × h a c k + 1 2\\times hack+1 2×hack+1 个相同字母,剩下的必须连在一起,那么最少对数就是 l = s u m − 2 × h a c k − 1 l = sum-2 \\times hack-1 l=sum−2×hack−1
判断 m m m 是否在区间内即可。
Code
// Problem: B. Combinatorics Homework
// Contest: Codeforces - Educational Codeforces Round 114 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1574/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e5 + 6, INF = 0x3f3f3f3f;
int n, m, s, t;
ll ans;
int a, b, c;
void solve()
{
cin >> a >> b >> c >> n;
int hack = a + b + c - max({a, b, c});
int l = a + b + c - 2 * hack - 1;
int r = a + b + c - 3;
if(l <= n && n <= r)
puts("YES");
else puts("NO");
}
int main()
{
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
C. Slay the Dragon
Problem
Solution
排序后直接 lower_bound
找到大于等于
x
x
x 的英雄
p
o
s
pos
pos 让他去杀 dragon 即可。
由于我们拥有强化的功能,所以需要判断一下让 p o s pos pos 去杀以及让 p o s − 1 pos-1 pos−1 强化之后去杀,谁更便宜即可。
Code
// Problem: C. Slay the Dragon
// Contest: Codeforces - Educational Codeforces Round 114 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1574/problem/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
#define int long long
using ll = long long;
const int maxn = 3e5 + 6, INF = 2e18;
int n, m, s, t;
ll ans;
int a[maxn];
void solve()
{
cin >> n;
int sum = 0;
int maxx = -INF;
for (int i = 1; i <= n; ++ i)
scanf("%lld", &a[i]), sum += a[i];
sort(a + 1, a + 1 + n);
cin >> m;
while(m -- ) {
int x, y;
scanf("%lld%lld", &x, &y);
ll ans = INF;
int pos = lower_bound(a + 1, a + 1 + n, x) - a;
if(pos != n + 1) {
int kill = a[pos];
int rem = sum - kill;
int res = max(0ll, y - rem);
ans = min(ans, res);
}
if(pos != 1) {
int kill = a[pos - 1];
int rem = sum - kill;
int res = max(0ll, y - (sum - a[pos - 1])) + x - a[pos - 1];
ans = min(ans, res);
}
cout << ans << endl;
}
}
signed main()
{
// cin >> t;
t = 1;
while(t -- ) {
solve();
}
return 0;
}
D. The Strongest Build
Problem
Solution
首先考虑如何判断某种选择方案是否被 ban,显然可以直接使用 hash 表 map
O
(
1
)
O(1)
O(1) 查询即可。我们将数组用 vector
存入,直接使用 map
判断是否存在这种 vector
即可。
由于输入的 a i j a_{ij} aij 是递增的,考虑暴力搜索,我们可以从最外层选择 c i c_i ci ,即 max { c i } , i ∈ [ 1 , n ] \\max\\{c_i\\},i\\in [1,n] max{ci},i∈[1,n] 开始往里 b f s bfs bfs 搜索即可,每次各减一步,一旦找到没有被 ban 的即为最大值。
我们在 bfs 搜索时,我们先判断最优解是否被 ban,若被 ban ,判断最优解的下一层也即某一个 i --
,判断此时是否被 ban 。但是我们发现 ban 掉的方案
m
≤
1
0
5
m\\le 10^5
m≤105,其实我们直接对所有的被 ban 的选择方案,仅判断他们的下一层即可。
对于限选方案 3 2 3
仅判断它的下一层: 2 2 3, 3 1 3, 3 2 2
即可。
此时时间复杂度为 O ( n m ) = 1 × 1 0 6 O(nm)=1\\times 10^6 O(nm)=1×106
因为从最优解开始,只有最优解以及其下一层的方案均被 ban 掉,才需要看下下一层,那么下一层在被 ban 的列表里也将会判断它的下一层。因此仅判断被 ban 的方案的下一层一定能找到可选的最优值。
Code
// Problem: D. The Strongest Build
// Contest: Codeforces - Educational Codeforces Round 114 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1574/problem/D
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
#define int long long
using ll = long long;
const int maxn = 2e5 + 6, INF = 0x3f3f3f3f, base = 13331, mod1 = 998244353, mod2 = 1e9 + 7;
int n, m, s, t;
vector <int> a[10], ans, b[maxn];
map <vector <int> , int> mp;
void solve()
{
cin >> n;
for (int i = 0; i < n; ++ i) {
int c;
scanf("%lld", &c);
ans.emplace_back(c - 1);
for (int j = 0; j < c; ++ j) {
int x;
scanf("%lld", &x);
a[i].emplace_back(x);
}
}
cin >> m;
for (int i = 0; i < m; ++ i) {
for (int j = 0; j < n; ++ j) {
int x;
scanf("%lld", &x);
x -- ;
b[i].emplace_back(x);
}
mp[b[i]] = 1;
}
if(mp.find(ans) == mp.end()) {
for (auto it : ans)
cout << it + 1 << ' ';
puts("");
return ;
}
int res = 0;
for (int i = 0; i < m; ++ i) {
int sum = 0;
for (int j = 0; j < n; ++ j)
sum += a[j][b[i][j]];
for (int j = 0; j < n; ++ j) {
sum -= a[j][b[i][j]];
if(b[i][j] == 0) continue;
b[i][j] -- ;
sum += a[j][b[i][j]];
if(mp.find(b[i]) == mp.end())
if(sum > res)
ans = b[i], res = sum;
sum -= a[j][b[i][j]];
b[i][j] ++ ;
sum += a[j][b[i][j]];
}
}
for (auto it : ans)
cout << it + 1 << ' ';
puts("");
}
signed main()
{
// cin >> t;
t = 1;
while(t -- ) {
solve();
}
return 0;
}
E. Coloring
Problem
Solution
官方题解:
为了更好地理解,我们将矩阵替换为 0 0 0 和 1 1 1 ,并使用带有黑白单元格的矩阵。
首先,让我们考虑如果有两个相邻的相同颜色的水平单元格
例如单元格
(
5
,
5
)
(5,5)
(5,5) 和
(
5
,
6
)
(5,6)
(5,6) 是黑色的矩阵,那么单元格
(
以上是关于Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解的主要内容,如果未能解决你的问题,请参考以下文章 Educational Codeforces Round 7 A Educational Codeforces Round 7 Educational Codeforces Round 90 Educational Codeforces Round 33