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.
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) 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
Proof of the card problem of circular equalization:
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>usingnamespace std;typedeflonglong ll;constint 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;}intmain(){
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;elseif(row !=-1) cout <<"row "<< row << endl;elseif(col !=-1) cout <<"column "<< col << endl;else cout <<"impossible"<< endl;return0;}