面试题之中位数的应用POJ1723

来源:互联网 发布:abb机器人编程调试 编辑:程序博客网 时间:2024/06/05 21:18

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;}


原创粉丝点击