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();
}

猜你喜欢

转载自www.cnblogs.com/Kanoon/p/12892382.html
今日推荐