莫欺少年穷,修魔之旅在这开始—>算法提高课题解
思路:
1. 目的是让每行和每列的糖果数一样多
2. 要让每行的糖果数一样多,就把每行看成一个点,按列的形式去交换糖果,反之,列亦可
3. 然后就变成了一个简单的糖果传递问题
4. 利用前缀和计算糖果总数
5. 推公式可得c[i] = i * avg - s[i];
6. 最后就是求数轴上一个点到其他所有点的距离和最小值问题了
可参考:糖果传递
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100010;
int n,m,cnt;
int row[N],col[N];
int s[N],c[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;
int avg=s[n]/n;
for(int i=1;i<=n;i++) c[i]=i*avg-s[i];
sort(c+1,c+n+1);
LL res=0;
for(int i=1;i<=n;i++) res+=abs(c[i]-c[(n+1)/2]);
return res;
}
int main()
{
cin>>n>>m>>cnt;
while(cnt--)
{
int x,y;
cin>>x>>y;
row[x]++,col[y]++;
}
LL r=work(n,row),c=work(m,col);
if(r!=-1&&c!=-1) cout<<"both "<<r+c<<endl;
else if(r!=-1) cout<<"row "<<r<<endl;
else if(c!=-1) cout<<"column "<<c<<endl;
else cout<<"impossible"<<endl;
return 0;
}