其他分享
首页 > 其他分享> > Codeforces Round #802 (Div. 2) 丢人日记+题解

Codeforces Round #802 (Div. 2) 丢人日记+题解

作者:互联网

2022.7.2晚

今晚刚打完ABC,感觉C比AB都要简单。D题实现不能,E题一眼但是时间来不及了
附上链接:AtCoder Beginner Contest 258 - AtCoder

明天得想个办法补一下ABC和洛谷的题(

好的,进入正题(分两天更新完,大概)

A. Optimal Path

链接:Problem - A - Codeforces

题意:给定一个\(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

链接:Problem - B - Codeforces

题意:给定一个长度为\(n\)的数\(a\),找到一个数\(b\)满足:\(b\)的长度是\(n\),\(a+b\)是一个回文数

解析:直接构造回文数的每一位都相同,于是有两种情况

  1. \(a\)的每一位都是9,这样的话,可以用\(n + 1\)位的1减去
  2. 用\(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

保护大自然

链接:Problem - C - Codeforces

题意:给定\(n\)个数,可以对其进行如下操作,使其全部变为$ 0$,求最少操作次数:

  1. 选择任意一个数\(a_i\),使所有\(a_{1\cdots i}\)减一
  2. 选择任意一个数\(a_i\),使所有\(a_{i \cdots n}\)减一
  3. 所有数加一

解析:

设\(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