七夕祭(中位数)

题面:

七夕祭

思路:

1、左右交换不影响行,上下交换不影响列,行和列分开讨论

2、参考糖果传递,明白中位数的意义,糖果传递

3、题目可转换为求|x1-c1|+|x1-c2|+|x1-c3|+…+|x1-cn|的最小(分别对行和列)
其中c1=0, c2=A1-ave, c3=a1+a2-2ave(其中ave为每个位置的最终数值(和除以个数)),以此类推。

4、即为求中位数

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
int n, m, t, x, y;
int h[maxn], l[maxn];
int  sum[maxn], c[maxn];

ll Fun(int a[], int n){
	for(int i=1; i<=n; i++)
		sum[i]=sum[i-1]+a[i];
	if(sum[n]%n)
		return -1;
	ll ave=sum[n]/n;
	c[1]=0;
	for(int i=2; i<=n; i++)
		c[i]=sum[i-1]-(i-1)*ave;
	sort(c+1, c+1+n);
	ll step=0;
	ll zd=c[(n+1)/2];
	for(int i=1; i<=n; i++)
		step+=abs(c[i]-zd);
	return step;
}

int main(){
	scanf("%d%d%d", &n, &m, &t);
	for(int i=0; i<t; i++){
		scanf("%d %d", &x, &y);
		h[x]++;
		l[y]++;
	}
	ll nx=Fun(h, n);
	ll my=Fun(l,m);
	if(nx!=-1&&my!=-1)
		printf("both %lld", nx+my);
	else if(nx!=-1)
		printf("row %lld", nx);
	else if(my!=-1)
		printf("column %lld", my);
	else 
		printf("impossible");
	printf("\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xmyrzb/article/details/107074530