一.题目链接:
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;
}