中位数性质(环形均分纸牌)
Posted kstranger
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中位数性质(环形均分纸牌)相关的知识,希望对你有一定的参考价值。
水了一个环形均分纸牌的问题:
叫七夕祭: 原题链接
这个题就是一个裸的环形均分纸牌问题
用到的性质每个数到中位数距离之和是最短的。
code:
#include <iostream> #include <cstring> #include <string> #include <algorithm> using namespace std; const int N = 1e5+10; typedef long long ll; //中位数性质:每个点到中位数距离之和一定是到任意点的距离之和的最小值 ll row[N],col[N]; ll srow[N],scol[N]; int main(){ int n,m,t; cin>>n>>m>>t; int sum=t; for(int i=0;i<t;i++){ int x,y; cin>>x>>y; row[x]++; col[y]++; } // cout<<t<<endl; if(sum%n!=0&&sum%m!=0){ cout<<"impossible"<<endl; return 0; } if(sum%n==0&&sum%m!=0){ srow[0]=0; int avg=sum/n; for(int i=1;i<=n;i++){ srow[i]=srow[i-1]+row[i]-avg; } sort(srow+1,srow+n+1); int mid=(1+n)>>1; ll cnt=0; for(int i=1;i<=n;i++){ cnt+=abs(srow[i]-srow[mid]); } cout<<"row "; cout<<cnt<<endl; return 0; } if(sum%n!=0&&sum%m==0){ scol[0]=0; int avg=sum/m; for(int i=1;i<=m;i++){ scol[i]=scol[i-1]+col[i]-avg; } sort(scol+1,scol+m+1); int mid=(1+m)>>1; ll cnt=0; for(int i=1;i<=m;i++){ cnt+=abs(scol[i]-scol[mid]); } cout<<"column "; cout<<cnt<<endl; return 0; } int avg1=sum/n,avg2=sum/m; srow[0]=0; for(int i=1;i<=n;i++){ srow[i]=srow[i-1]+row[i]-avg1; } sort(srow+1,srow+n+1); int mid=(1+n)>>1; ll cnt1=0; for(int i=1;i<=n;i++){ cnt1+=abs(srow[i]-srow[mid]); } scol[0]=0; for(int i=1;i<=m;i++){ scol[i]=scol[i-1]+col[i]-avg2; } sort(scol+1,scol+m+1); mid=(1+m)>>1; ll cnt2=0; for(int i=1;i<=m;i++){ cnt2+=abs(scol[i]-scol[mid]); } cout<<"both "; cout<<cnt1+cnt2<<endl; return 0; }
以上是关于中位数性质(环形均分纸牌)的主要内容,如果未能解决你的问题,请参考以下文章