水了一个环形均分纸牌的问题:
叫七夕祭:原题链接
这个题就是一个裸的环形均分纸牌问题
用到的性质每个数到中位数距离之和是最短的。
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; }
原文地址:https://www.cnblogs.com/kstranger/p/12420933.html
时间: 2024-10-28 12:59:12