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