Hướng dẫn giải của Bedao Grand Contest 12 - ODDEVEN


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Tác giả: bedao

Gọi số lượng số chẵn trong dãy là ~E~. Số lượng số lẻ trong dãy là ~O~. Ta nhận thấy đáp án là ~-1~ khi điều kiện sau sai: ~E = \lfloor \frac{n}{2} \rfloor~ và ~O = \lfloor \frac{n + 1}{2} \rfloor~.

Ngược lại, ta có nhận xét là việc swap các số chẵn về đúng vị trí và các số lẻ về đúng vị trí là như nhau. Gọi các vị trí hiện tại của các số chẵn là ~i_1 < i_2 < ... < i_{E}~. Các vị trí có chỉ số chẵn là ~2, 4, ..., E \times 2~. Ta có thể chứng minh số phép swap ít nhất luôn bằng:

$$|i_1 - 2| + |i_2 - 4| + ... + |i_E - E \times 2|$$.

Code mẫu

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 1e6 + 5;

int n;
vector<int> a, b;

void solve() {
    cin >> n;
    for (int i = 1; i <= n; ++ i) {
        int x;
        cin >> x;
        if (x & 1) a.push_back(i);
        else b.push_back(i);
    }
    if (a.size() != (n + 1) / 2 || b.size() != n / 2) {
        cout << -1;
        return;
    }
    ll res = 0, ans = 0;
    for (int i = 1; i <= n / 2; ++ i) {
        res += abs(b[i - 1] - i * 2);
    }
    for (int i = 1; i <= n / 2; ++ i) {
        ans += abs(a[i - 1] - (i * 2 - 1));
    }
    assert(res == ans);
    cout << res;
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    solve();
    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.