Algorithm Competition Advanced Guide---0x05 (Sort) Qixi Festival

Topic

Insert picture description here

answer

  1. We can find that the exchange of rows and rows (up and down) has no effect on the columns, and the exchange of columns and columns (left and right) has no effect on the rows. That is to say, the exchange of rows and columns are independent of each other, so the minimum number of total exchanges can be changed to the minimum of rows and columns, and then add them.
  1. Then when we exchange (up and down) when seeking rows, we can regard each row as a whole, that is, a number, and the same is true for the columns. This becomes the problem of equal distribution of circular cards (note: here a refers to It is the sum of each row) Insert picture description here
    We only need to specify one direction (counterclockwise in the figure), x1 means how many a1 gives an, of course x1 can be a positive or negative number or zero, and a negative number means an is given to a1, then we are now looking for The minimum value of |x1|+|x2|+|x3|+…+|x4|+|x5| is the minimum number of exchanges
  1. Proof of the card problem of circular equalization:
    Insert picture description here
    After derivation, we transform it into a classic warehouse location problem, and the optimal solution is the median

Code

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>

using namespace std;
typedef long long ll;
const int N = 1e5 + 10;

ll x[N], y[N], s[N], c[N];

ll slove(ll n, ll a[]) {
    
    

    for (int i = 1; i <= n; i++) s[i] = s[i - 1] + a[i];

    if (s[n] % n) return -1;

    ll avg = s[n] / n;

    c[1] = 0;
    for (int i = 2; i <= n; i++) {
    
    
        c[i] = s[i - 1] - (i - 1) * avg;
    }

    sort(c + 1, c + 1 + n);

    ll res = 0;
    for (int i = 1; i <= n; i++) res += abs(c[i] - c[(n + 1) / 2]);

    return res;

}


int main() {
    
    

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    ll n, m, t;

    cin >> n >> m >> t;
    while (t--) {
    
    
        int a, b;
        cin >> a >> b;
        x[a]++, y[b]++;
    }

    ll row = slove(n, x);
    ll col = slove(m, y);

    if (row != -1 && col != -1) cout << "both " << row + col << endl;
    else if (row != -1) cout << "row " << row << endl;
    else if (col != -1) cout << "column " << col << endl;
    else cout << "impossible" << endl;

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_44791484/article/details/114608790