题目链接:acwing 105 七夕祭
前置题目:acwing 104 货仓选址、acwing 122 糖果传递
本题和糖果传递问题是相同的思路,区别就是把一维问题变成了二维问题,只需要对行和列分别按“糖果传递”问题的思路求解即可。
#include<cstdio>
#include<algorithm>
#include <vector>
#define PII pair<int, int>
using namespace std;
// 【注】行上的交换行为不会对列上的个数产生任何影响
int n, m, T;
vector<PII> a;
long long cal(int x) {
int len = x == 1 ? m : n;
vector<int> b(len + 2, 0);
for (auto p : a) { // 把行/列压缩到一维(像串糖葫芦),然后就是“货仓选址”问题
if (x == 0) b[p.first]++;
else b[p.second]++;
}
int avg = T / len;
for (int i = len; i >= 2; i--)
b[i] = b[i + 1] + b[i] - avg;
b[1] = 0;
sort(b.begin() + 1, b.begin() + len + 1);
int mid = (len >> 1) + 1;
long long res = 0;
for (int i = 1; i <= len; ++i) res += abs(b[mid] - b[i]);
return res;
}
int main() {
scanf("%d %d %d", &n, &m, &T);
int t1, t2;
for (int i = 0; i < T; ++i) {
scanf("%d %d", &t1, &t2);
a.push_back({t1, t2});
}
long long res = 0;
if (T % n == 0 && T % m == 0) {
res = cal(0) + cal(1); // 先后计算行/列的“货仓选址”问题
printf("both %lld", res);
} else if (T % n == 0) {
res = cal(0);
printf("row %lld", res);
} else if (T % m == 0) {
res = cal(1);
printf("column %lld", res);
} else {
printf("impossible");
}
return 0;
}