【解题报告】 BZOJ3032 七夕祭
题目:七夕祭(翻译过的)
ps:话说今天是七夕节,我就正好做到七夕祭
解题思路:
看到这道题的题目,可以想到《均分纸牌》和我之前做的《货仓选址》两题,这样经过思考,演算和推理,我们可以得出,需要的最少步数是
[sumlimits_{i=1}^Mleft|S[i]-s[k]
ight|
]
其中S是A的前缀和,即
[S[i]=sumlimits_{j=1}^iA[j]
]
所以经过简单地编码,答案就出来了
AC代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=100005;
long long a[maxn],b[maxn];
long long f[maxn];
long long n,m,t;
long long x,y;
long long calc(long long a[],long long n)
{
for(int i=1;i<=n;i++)
{
a[i]-=(a[0]/n);
f[i]=f[i-1]+a[i];
}
sort(f+1,f+n+1);
long long mid=(n+1)>>1,ans=0;
for(int i=1;i<=n;i++)
ans+=abs(f[mid]-f[i]);
return ans;
}
int main()
{
cin>>n>>m>>t;
for(int i=1;i<=t;i++)
{
cin>>x>>y;
a[x]++;
b[y]++;
}
for(int i=1;i<=n;i++)
a[0]+=a[i];
for(int i=1;i<=m;i++)
b[0]+=b[i];
long long c=a[0]%n,d=b[0]%m;
if(!c&&!d)
cout<<"both "<<calc(a,n)+calc(b,m);
else if(!c)
cout<<"row "<<calc(a,n);
else if(!d)
cout<<"column "<<calc(b,m);
else
cout<<"impossible";
cout<<endl;
return 0;
}