BZOJ3032 七夕祭
阿新 • • 發佈:2019-01-05
題解
容易看出來,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;
}