POJ1723 SOLDIERS【中位数+排序】

问题链接POJ1723 SOLDIERS

问题简述:有N个士兵,每个士兵开始站的坐标是(x,y),现在使得将N个士兵站在同一个水平线(即所有士兵的y坐标相同)并且x坐标相邻,每个士兵每次可以移动一个位置(分别在x和y方向移动)。求出最少的移动步数。

问题分析

这是一个最优化问题,可以使用中位数计算来解决。

x方向和y方向可以分别来考虑。

y方向就是一个简单的中位数计算。

x方向是坐标相邻,可以先将x位置排序,然后往中间靠,也是一个中位数计算问题。x方向分别移动到a+i的位置,那么士兵就相邻了,即x[i]=a+i,那么x[i]-i=a。用中位数来算的话,首先将x方向进行排序,然后让x[i]=x[i]-i,再次排序后求中位数即可。

程序说明:(略)

题记(略)


AC的C++语言程序如下:

/* POJ1723 SOLDIERS */

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 10000;
int x[N], y[N];

int main()
{
    int n;

    while(cin >> n) {
        for(int i=0; i<n; i++)
            cin >> x[i] >> y[i];

        sort(x, x + n);
        for(int i=0; i<n; i++)
            x[i] -= i;
        sort(x, x + n);
        sort(y, y + n);

        int ans = 0, x_median, y_median;
        if(n % 2 == 1) {
            x_median = x[n / 2];
            y_median = y[n / 2];
        } else {
            x_median = (x[n / 2 - 1] + x[n / 2]) / 2;
            y_median = (y[n / 2 - 1] + y[n / 2]) / 2;
        }
        for(int i=0; i<n; i++)
            ans += abs(x_median - x[i]) + abs(y_median - y[i]);

        cout << ans << endl;
    }

    return 0;
}




原文地址:https://www.cnblogs.com/tigerisland/p/7563747.html