题解:P10453 七夕祭
link
题意
给定一个
前置知识
P2512 [HAOI2008] 糖果传递
即环形均分纸牌。
令
假设在第
可以发现全部减去了
就转化成了货仓选址问题,直接取中位数即可。
思路
由于交换行之间的点不会改变列的关键点数,交换列之间的点不会改变行的关键点数,我们可以把行列分开处理。
对于行,可以把每一行的关键点数当作糖果传递处理;对于列同理。
代码
// BLuemoon_
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int kMaxN = 1e5 + 5;
LL n, m, t, sl, sr, a[kMaxN], b[kMaxN], l[kMaxN], r[kMaxN], ls[kMaxN], rs[kMaxN], ans;
bool L, R;
int main() {
cin >> n >> m >> t, L = t % n == 0, R = t % m == 0;
for (int i = 1; i <= t; i++) {
cin >> a[i] >> b[i], l[a[i]]++, r[b[i]]++;
}
if (!L && !R) {
return cout << "impossible\n", 0;
}
cout << (L && R ? "both" : (L ? "row" : "column")) << ' ';
sl = t / n, sr = t / m;
if (L) {
for (int i = 1; i <= n; i++) {
l[i] -= sl, ls[i] = ls[i - 1] + l[i];
}
}
if (R) {
for (int i = 1; i <= m; i++) {
r[i] -= sr, rs[i] = rs[i - 1] + r[i];
}
}
sort(ls + 1, ls + n + 1), sort(rs + 1, rs + m + 1);
if (L) {
for (int i = 1; i <= n; i++) {
ans += abs(ls[i] - ls[(n + 1) >> 1]);
}
}
if (R) {
for (int i = 1; i <= m; i++) {
ans += abs(rs[i] - rs[(m + 1) >> 1]);
}
}
cout << ans << '\n';
return 0;
}