Codeforces Round #802 (Div. 2) 丢人日记+题解
作者:互联网
2022.7.2晚
今晚刚打完ABC,感觉C比AB都要简单。D题实现不能,E题一眼但是时间来不及了
附上链接:AtCoder Beginner Contest 258 - AtCoder
明天得想个办法补一下ABC和洛谷的题(
好的,进入正题(分两天更新完,大概)
A. Optimal Path
题意:给定一个\(n\)行\(m\)列的表格,表格中从左到右从上到下填上数字,从左上角走到右下角,问途经的数字之和最少是多少。
解析:无脑暴力for()
一遍,或者等差数列求和\(\displaystyle \sum^{m}_{i = n}{a_i}=\frac{(a_n+a_m)(m - n + 1)}{2}\)
代码:
#include <iostream>
#include <algorithm>
using namespace std;
using i64 = long long;
void solve() {
i64 n, m;
cin >> n >> m;
i64 ans = 0;
for (i64 i = 1; i < m; i++) {
ans += i;
}
for (i64 i = m; i <= n * m; i += m) {
ans += i;
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
B. Palindromic Numbers
题意:给定一个长度为\(n\)的数\(a\),找到一个数\(b\)满足:\(b\)的长度是\(n\),\(a+b\)是一个回文数
解析:直接构造回文数的每一位都相同,于是有两种情况
- \(a\)的每一位都是9,这样的话,可以用\(n + 1\)位的1减去
- 用\(n\)位9减去\(a\)
由于 $ 2\leq n \leq 100,000$,所以要写个高精 (或者直接用Python交
代码如下,简单写了个高精减法:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
using i64 = long long;
void solve() {
int n;
cin >> n;
string s;
cin >> s;
vector<int> a;
if (s[0] == '9') {
int tmp = 0;
for (int i = s.length() - 1; i >= 0; i--) {
if ('1' + tmp >= s[i]) {
a.push_back('1' + tmp - s[i]);
tmp = 0;
} else {
a.push_back('1' + tmp + 10 - s[i]);
tmp = -1;
}
}
} else {
for (int i = s.length() - 1; i >= 0; i--) {
a.push_back('9' - s[i]);
}
}
for (int i = a.size() - 1; i >= 0; i--) {
cout << a[i];
}
cout << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
C. Helping the Nature
保护大自然
题意:给定\(n\)个数,可以对其进行如下操作,使其全部变为$ 0$,求最少操作次数:
- 选择任意一个数\(a_i\),使所有\(a_{1\cdots i}\)减一
- 选择任意一个数\(a_i\),使所有\(a_{i \cdots n}\)减一
- 所有数加一
解析:
设\(a\)和\(b\)是中间的两个数,\(a - b = d\),若\(d>0\),则进行\(d\)次①操作后能使\(a=b\);反之则进行\(d\)次②操作后能使\(a=b\)。
现在,我们从最后一位数开始操作,每次操作使这一位及之后的数都等于它前一位数,那么到最后一次操作后,所有的数都等于第一位数,最后轻松得到\(n\)位$ 0$.
由于对所有数操作不方便,所以要用差分数组,故核心代码应该是:
vector<int> d(n);
for (int i = 0; i < n - 1; i++) {
d[i] = a[i + 1] - a[i];
}
i64 ans = 0;
for (int i = 0; i < n - 1; i++) {
if (d[i] < 0) {
ans -= d[i];
} else {
ans += d[i];
d[0] += d[i];
}
}
cout << ans + abs(d[0]) << '\n';
考虑到\(d_n\)数组中的大部分数不参与最终计算,所以这一部分可以简化为:
i64 ans = 0;
i64 a0 = a[0];
for (int i = n - 2; i >= 0; i--) {
int d = a[i + 1] - a[i];
if (d > 0) {
ans += d;
} else {
ans -= d;
a0 += d;
}
}
cout << ans + abs(a0) << '\n';
完整代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
using i64 = long long;
void solve() {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
i64 ans = 0;
i64 a0 = a[0];
for (int i = n - 2; i >= 0; i--) {
int d = a[i + 1] - a[i];
if (d > 0) {
ans += d;
} else {
ans -= d;
a0 += d;
}
}
cout << ans + abs(a0) << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
(分割线,明天更新)
标签:int,题解,Codeforces,i64,--,ans,using,include,Round 来源: https://www.cnblogs.com/isrol/p/16438962.html