面试题之中位数的应用POJ1723

http://poj.org/problem?id=1723

这种难度的题也可以用来当面试题。

题意:一些士兵站在矩阵的一些方格内,现要把他们移动到一横排,并连续地排成一队,问最少需要移动多少步。N<=10000,-10000<=X,Y<=10000

解题思想:

S=|x[1]-k|+|x[2]-k|+...+|x[n]-k|,当 k 为序列 x 的中位数时,S 取最小值。
因此对于 y 坐标的确定较简单,找出中位数即可。
x 方向要排成 x,x + 1,x + 2....x + n-1,换言之,它们最终的 x 坐标一定是相连的。
只要找到一个确定的点就可以确定新的 x 序列了。
假如排好后最左边的坐标为 k,则移动的步数就是|x[0]-k|+|x[1]-(k+1)|+|x[2]-(k+2)|+...+|x[n]-(k+n)|,就是|x[0]-k|+|x[1]-1-k|+|x[2]-2-k|+..+|x[n]-n-k|,所以 k 为新的 x 序列的中位数。对 x[i] 排序,求出 x[i]-i,再排序,求出 S。

附代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int cmp(const void *a, const void *b)
{
	return *(int *)a - *(int *)b;
}

int main()
{
	int n, i, x_mid, y_mid, sum;
	while (scanf("%d", &n) != EOF)
	{
		sum = 0;
		int *x = malloc(sizeof(int) * n);
		int *y = malloc(sizeof(int) * n);
		for (i = 0; i < n; i++)
			scanf("%d %d", &x[i], &y[i]);
		
		qsort(y, n, sizeof(int), cmp);
		y_mid = y[n/2];
		for (i = 0; i < n; i++)
			sum += abs(y[i] - y_mid);

		qsort(x, n, sizeof(int), cmp);
		for (i = 0; i < n; i++)
			x[i] -= i;
		qsort(x, n, sizeof(int), cmp);
		x_mid = x[n/2];
		for (i = 0; i < n; i++)
			sum += abs(x[i] - x_mid);
	
		printf("%d\n", sum);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值