每日一题——七夕祭

题目

七夕祭

题解

这里借y总的图来用用,我们可以用正负来表示拿过来还是送出去,最终要每个人均分,所以可以列出n个方程,而这个方程组有一个自由变量(因为所有方程相加为恒等式,具体原理去看看线代),我们设x1为自由变量,通过移项可以用x1来表示其他所有x,用c表示后面的常量。我们本来求的是|x1|+|x2|+...+|xn|的最小值就可以转化成求|x1-c1|+|x1-c2|+...+|x1-cn|的最小值,那么就可以回到前面的货仓问题了。只能说这种想法太牛了已经给跪了orz



参考代码

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n, m, t;
int s[N], c[N];
int col[N], row[N];
LL work(int n, int a[]){
    for(int i = 1; i <= n; i ++) s[i] = s[i - 1] + a[i];
    if(s[n] % n) return -1;
    c[1] = 0;
    int avg = s[n] / n;
    for(int i = 2; i <= n; i ++) c[i] = s[i - 1] - (i - 1) * avg;
    sort(c + 1, c + n + 1);
    LL res = 0;
    for(int i = 1; i <= n; i ++) res += abs(c[i] - c[(1 + n) / 2]);
    return res;
}
int main(){
    cin >> n >> m >> t;
    int x, y;
    for(int i = 1; i <= t; i ++){
        cin >> x >> y;
        row[x] ++;
        col[y] ++;
    }
    LL r = work(n, row);
    LL c = work(m, col);
    if(r == -1 && c == -1) puts("impossible");
    else if(r == -1) cout << "column " << c << endl;
    else if(c == -1) cout << "row " << r << endl;
    else cout << "both " << r + c << endl;
    return 0;
}
posted @ 2025-03-14 21:48  PZnwbh  阅读(11)  评论(0)    收藏  举报