Codeforces Round #642 (Div. 3)
比赛链接:https://codeforces.com/contest/1353
A - Most Unstable Array
题意
构造大小为 $n$,和为 $m$ 的非负数组 $a$,使得相邻元素之差的绝对值之和最大。
题解
稍加推导发现:将 $m$ 拆分和单独用 $m$ 结果是一样的,所以可以直接用 $0$ 和 $m$ 构造。
代码
#include <bits/stdc++.h>
using namespace std; void solve() {
int n, m; cin >> n >> m;
if (n == 1) cout << 0 << "\n";
else if (n == 2) cout << m << "\n";
else cout << 2 * m << "\n";
} int main() {
int t; cin >> t;
while (t--) solve();
}
B - Two Arrays And Swaps
题意
有大小为 $n$ 的数组 $a$ 和 $b$,最多可以交换 $a$ 中某一元素和 $b$ 中某一元素 $k$ 次,问数组 $a$ 中元素的最大和为多少。
题解
取 $a$ 中 $n$ 个和 $b$ 中前 $k$ 大个元素中前 $n$ 大个元素即可。
代码
#include <bits/stdc++.h>
using namespace std; void solve() {
int n, k; cin >> n >> k;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
vector<int> b(n);
for (int i = 0; i < n; i++) {
cin >> b[i];
}
sort(b.rbegin(), b.rend());
for (int i = 0; i < k; i++) {
a.push_back(b[i]);
}
sort(a.rbegin(), a.rend());
cout << accumulate(a.begin(), a.begin() + n, 0) << "\n";
} int main() {
int t; cin >> t;
while (t--) solve();
}
C - Board Moves
题意
有一边长为奇数 $n$ 的正方形网格,每一次一个方块可以移到相邻八个位置中的某一个,问所有方块移到一个位置最少需要移动几次。
题解
从中心考虑:中心外第 $i$ 圈的每个方块移到中心需要 $i$ 步。
代码
#include <bits/stdc++.h>
using ll = long long;
using namespace std; void solve() {
int n; cin >> n;
ll ans = 0, a = 3, b = 1;
for (ll i = 1; i <= (n - 1) / 2; i++) {
ans += (a * a - b * b) * i;
a += 2, b += 2;
}
cout << ans << "\n";
} int main() {
int t; cin >> t;
while (t--) solve();
}
D - Constructing the Array
题意
有一大小为 $n$ 初始时每个元素均为 $0$ 的数组,第 $i$ 次操作如下:
- 选取最长最靠左的一段连续为 $0$ 的子区间
- 如果区间长度为奇数,$a_{\frac{l+r}{2}} = i$
- 如果区间长度为偶数,$a_{\frac{l+r-1}{2}} = i$
输出进行 $n$ 次操作后的数组。
题解
递归分解区间,按照题意排序赋值即可。
代码
#include <bits/stdc++.h>
using namespace std; vector<pair<int, int>> v; int cal(int l, int r) {
return ((r - l + 1) % 2 == 1) ? (l + r) / 2 : (l + r - 1) / 2;
} void recur(int l, int r) {
if (l > r) return;
v.push_back({l, r});
recur(l, cal(l ,r) - 1);
recur(cal(l ,r) + 1, r);
} void solve() {
v.clear();
int n; cin >> n;
recur(1, n);
sort(v.begin(), v.end(), [&] (pair<int, int> a, pair<int, int> b) {
if (a.second - a.first != b.second - b.first)
return a.second - a.first > b.second - b.first;
else
return a.first < b.first;
});
int a[n + 1] = {};
for (int i = 0; i < n; i++)
a[cal(v[i].first ,v[i].second)] = i + 1;
for (int i = 1; i <= n; i++)
cout << a[i] << " \n"[i == n];
} int main() {
int t; cin >> t;
while (t--) solve();
}
E - K-periodic Garland
题意
将一个 $01$ 串变为相邻两个 $1$ 之间周期为 $k$ 的字符串最少需要改变多少字符。
题解
把原字符串分为 $k$ 个周期子串,每次考虑一个子串时需要将其他子串中的 $1$ 都变为 $0$,然后对当前周期子串进行 $dp$,$dp_i$ 表示周期子串中位置 $i$ 的字符变为 $1$,之前的字符变为合法至少需要改变多少字符。
代码
#include <bits/stdc++.h>
using namespace std; int cal(const string &s) {
int n = s.size();
int all = count(s.begin(), s.end(), '1');
int dp[n] = {};
int pref = 0;
int ans = all;
for (int i = 0; i < n; i++) {
int cur = (s[i] == '1');
pref += cur;
dp[i] = 1 - cur;
if (i > 0) dp[i] += min(dp[i - 1], pref - cur);
ans = min(ans, dp[i] + all - pref);
}
return ans;
} void solve() {
int n, k; cin >> n >> k;
string s; cin >> s;
int tot_one = count(s.begin(), s.end(), '1');
vector<string> v(k);
for (int i = 0; i < k; i++)
for (int j = i; j < n; j += k)
v[i] += s[j];
int ans = 1e9;
for (auto &it : v)
ans = min(ans, cal(it) + tot_one - count(it.begin(), it.end(), '1'));
cout << ans << "\n";
} int main() {
int t; cin >> t;
while (t--) solve();
}
F - Decreasing Heights
题意
有一个 $n * m$ 、高度不等的三维坐标系,从 $a_{00}$ 走到 $a_{{(n-1)}{(m-1)}}$,每次只能从 $a_{ij}$ 向 $a_{(i+1)j}$ 或 $a_{i(j+1)}$ 行走,且 $a_{xy} - a_{ij} = 1$,每个位置的高度可以不限次地 $-1$,问最少需要减少多少高度。
题解
如果 $a_{00}$ 是确定的,那么每个点 $a_{ij}$ 的高度应为 $a_{00} + i + j$,因为每移动一格高度都会 $+1$,这与路径无关。
那么,根据状态转移方程:
$dp_{ij} = min(dp_{{(i - 1)}{j}} + dp_{{i}{(j - 1)}}) + a_{ij} - (a_{00} + i + j)$
推导即可。
但是 $a_{00}$ 需要变化的高度是不确定,注意到如果有一条从 $a_{00}$ 到 $a_{{(n-1)}{(m-1)}}$ 的最优路径,那么这条路径上一定有点的高度不需要减少,因为如果都需要减少,那么可以增加 $a_{00}$ 的高度来抵消共同减少的部分,如果增加后的高度高于 $a_{00}$,呢么 $a_{00}$ 不需要减少,这条路径上的的高度都需要减少,即仍有点的高度不需要减少。
至此,可以枚举高度不变化的点反推出 $a_{00}$ 的高度,由此得解。
代码
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
const ll INF = 1e18; void solve() {
int n, m; cin >> n >> m;
ll a[n][m] = {};
for (int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
cin >> a[i][j];
ll ans = INF;
for (int x = 0; x < n; x++) {
for(int y = 0; y < m; y++) {
ll a_00 = a[x][y] - x - y;
if (a_00 > a[0][0]) continue;
ll dp[n][m] = {};
fill(*dp, *dp + n * m, INF);
dp[0][0] = a[0][0] - a_00;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
ll a_ij = a_00 + i + j;
if (a_ij > a[i][j]) continue;
if (i > 0) dp[i][j] = min(dp[i][j], dp[i - 1][j] + a[i][j] - a_ij);
if (j > 0) dp[i][j] = min(dp[i][j], dp[i][j - 1] + a[i][j] - a_ij);
}
}
ans = min(ans, dp[n - 1][m - 1]);
}
}
cout << ans << "\n";
} int main() {
int t; cin >> t;
while (t--) solve();
}
Codeforces Round #642 (Div. 3)的更多相关文章
- Codeforces Round #642 (Div. 3) D. Constructing the Array (优先队列)
题意:有一个长度为\(n\)元素均为\(0\)的序列,进行\(n\)次操作构造出一个新序列\(a\):每次选择最长的连续为\(0\)的区间\([l,r]\),使得第\(i\)次操作时,\(a[\fra ...
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
- Codeforces Round #262 (Div. 2) 1003
Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...
- Codeforces Round #262 (Div. 2) 1004
Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...
- Codeforces Round #371 (Div. 1)
A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...
随机推荐
- HP(惠普)服务器 修复 Intelligent Provisioning(摘录)
摘录自:https://www.xxshell.com/1219.html 我们在给惠普服务器安装操作系统和配置RAID最常用的就是通过F10(Intelligent Provisioning)进行, ...
- Python在项目外更改项目内引用
前言 目前有一个奇葩的需求, 将某个开源项目整合进自己的项目里去调度, 还需要在每次启动这个开源项目时, 加载不同的配置文件进去, 问题是配置文件并不是一个 conf 或者是其他的什么, 而是以 .p ...
- .NET 5 程序高级调试-WinDbg
上周和大家分享了.NET 5开源工作流框架elsa,程序跑起来后,想看一下后台线程的执行情况.抓了个进程Dump后,使用WinDbg调试,加载SOS调试器扩展,结果无法正常使用了: 0:000> ...
- 【二分搜索树】1、二分查找法的实现 - Binary Search
简单记录 - bobo老师的玩转算法系列–玩转算法 - 二分搜索树 二叉搜索树 Binary Search Tree 查找问题 Searching Problem 查找问题是计算机中非常重要的基础问题 ...
- 【Linux】ssh互信脚本
使用互信脚本的时候,需要敲回车,但是shell脚本无法满足,所以需要用到expect脚本 rpm -qa | grep expect 如果没有的话,直接用yum安装即可 yum install exp ...
- RWCTF2020 DBaaSadge 复现
数据库题目 2020RWCTF DBaaSadge WP 这是一个很有意思的题目,难到让我绝望,跟着大佬smity的思路跑一下,求大佬抱抱. https://mp.weixin.qq.com/s/jv ...
- 并发条件队列之Condition 精讲
1. 条件队列的意义 Condition将Object监控器方法( wait , notify和notifyAll )分解为不同的对象,从而通过与任意Lock实现结合使用,从而使每个对象具有多个等待集 ...
- libuv中实现tcp服务器
目录 1.说明 2.libuv的tcp server 3.API简介 3.1.uv_tcp_init 3.2.uv_ip4_addr 3.3.uv_tcp_bind 3.4.uv_listen 3.5 ...
- jackson学习之四:WRAP_ROOT_VALUE(root对象)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- git database 数据库 平面文件 Git 同其他系统的重要区别 Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异 Git 的设计哲学
小结: 1.如果要浏览项目的历史更新摘要,Git 不用跑到外面的服务器上去取数据回来 2.注意 git clone 应指定版本,它复制的这个版本的全部历史信息: 各个分支 git init 数据库 ...