poj1723

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

分析:先将他们移动到同一横排,这横排应该是他们纵坐标的中位数,才能使得此过程总步数最少。然后要把他们紧凑起来。我们先把横坐标排序,并假设起点是a,那么我们就是要求i=1~n,abs(a+i - xi)的加和。即i=1~n,abs(a-(xi - i))的加和。我们构建一个新数列zi = xi - i,当a 等于z的中位数时原式的值最小。

综上我们可以得到一个普遍结论,就是对于一个数列Xi(i=1~n),取一个X使得i=1~n时abs(Xi-A)的加和最小,那么A应该是数列Xi的中位数。Xi不一定是直接给出的,可能是一个关于已知量的表达式。

View Code
#include < iostream >
#include
< cstdio >
#include
< cstdlib >
#include
< cstring >
#include
< algorithm >
using namespace std;

#define maxn 10004

int n;
int x[maxn], y[maxn];

int main()
{
// freopen("t.txt", "r", stdin);
scanf( " %d " , & n);
for ( int i = 0 ; i < n; i ++ )
scanf(
" %d%d " , & x[i], & y[i]);
sort(y, y
+ n);
sort(x, x
+ n);
for ( int i = 0 ; i < n; i ++ )
x[i]
-= i;
sort(x, x
+ n);
int a = (n + 1 ) / 2 - 1 ;
int ans = 0 ;
for ( int i = 0 ; i < n; i ++ )
ans
+= abs(y[a] - y[i]) + abs(x[a] - x[i]);
printf(
" %d\n " , ans);
return 0 ;
}

你可能感兴趣的:(poj)