【解题报告】 BZOJ3032 七夕祭
题目:七夕祭(翻译过的)
ps:话说今天是七夕节,我就正好做到七夕祭
解题思路:
看到这道题的题目,可以想到《均分纸牌》和我之前做的《货仓选址》两题,这样经过思考,演算和推理,我们可以得出,需要的最少步数是
i=1∑M∣S[i]−s[k]∣
其中S是A的前缀和,即
S[i]=j=1∑iA[j]
所以经过简单地编码,答案就出来了
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #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; }
|