一.题目链接:

POJ-1723

二.题目大意:

有 n 个士兵,每人可向上下左右移动

问使士兵移到同一行,且相邻的最小步数.

三.分析:

先分析 y:易得移动到中位数的步数最小

当加入变量 x 后,由于 y 的改变不会影响 x 的移动步数.

所以,先保证 y 的移动最小,在此情况下,使 x 的移动步最小.

对 x 排序后

假设最终的 x 起点为 s

则:

x[0] 要到达 s

x[1] 要到达 s + 1

...........................

x[n - 1] 要到达 s + n - 1

所花费的步数为:

x[0] - 0

x[1] - 1

...........

x[n - 1] - (n - 1)

即:将 x[i] - i 看做新数列,取中位数即可.

四.代码实现:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define lc k * 2
#define rc k * 2 + 1
#define pi acos(-1.0)
#define ll long long int
using namespace std;

const int M = (int)1e4;
const ll mod = (ll)1e6 + 3;
const ll inf = 0x3f3f3f3f3f;

int x[M + 5];
int y[M + 5];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d %d", &x[i], &y[i]);
    sort(x + 1, x + n + 1);
    sort(y + 1, y + n + 1);
    for(int i = 1; i <= n; ++i)
        x[i] -= i;
    sort(x + 1, x + n + 1);
    int dis = 0;
    int pos = n / 2 + 1;
    for(int i = 1; i <= n; ++i)
        dis += (int)abs(x[pos] - x[i]) + (int)abs(y[pos] - y[i]);
    printf("%d\n", dis);
    return 0;
}