题解
容易看出来,impossible怎么判。。
容易看出来,行和列是互不影响的
容易看出来,这是一个糖果传递
于是我就想了1h+都没有想到糖果传递怎么做。。
怎么想都只会
的,显然不可行。。
然后YY了一个错误的
越来越垃圾了啊
为了惩罚自己,这次写一篇博客记录一下
我们假设第i个人,给了i-1X个糖果
如果i是1,那么i-1就是n
如果X是负的就是从别人那里拿过来的
那么我们就是要让
最小
然后我们知道每一个数最后要变成o,一开始每一个数是
那么可以得到式子
,化简可得
,化简可得
,化简可得
……
然后我们可以发现,一旦
固定了,剩下都出来了
并且
,
,
都是常数
那么就是给定平面上的一堆点,你要找一个X,使得X到这些点的距离最小化
那么X选中位数就可以了
记得这个模型做了一次,复习了一次,都没有记住
希望这次可以记住了
CODE:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const LL N=100005;
const LL MAX=(1<<28);
LL n,m,k;
LL x[N],y[N];
LL ans=0;
LL c[N];
void solve_a()
{
LL lalal=k/n;
for (LL u=2;u<=n;u++) c[u]=c[u-1]+lalal-x[u];
sort(c+1,c+1+n);
LL mid=c[n/2+1];
for (LL u=1;u<=n;u++) ans=ans+abs(c[u]-mid);
}
void solve_b()
{
LL lalal=k/m;
for (LL u=2;u<=m;u++) c[u]=c[u-1]+lalal-y[u];
sort(c+1,c+1+m);
LL mid=c[m/2+1];
for (LL u=1;u<=m;u++) ans=ans+abs(c[u]-mid);
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&k);
for (LL u=1;u<=k;u++)
{
LL xx,yy;
scanf("%lld%lld",&xx,&yy);
x[xx]++;y[yy]++;
}
if (k%n==0&&k%m==0) {printf("both ");solve_a();solve_b();printf("%lld\n",ans);return 0;}
if (k%n==0){printf("row ");solve_a();printf("%lld\n",ans);return 0;}
if (k%m==0){printf("column ");solve_b();printf("%lld\n",ans);return 0;}
printf("impossible\n");
return 0;
}