#士兵战队问题

#士兵战队问题,第1张

#士兵战队问题 Description

在一个划分成网格的 *** 场上,n个士兵散乱地站在网格点上。网格点由整数坐标(x,y)表示。士兵们可 以沿网格边上、下、左、右移动一步,但在同一时刻任一网格点上只能有一名士兵。按照军官的命令,士 兵们要整齐地列成一个水平队列,即排列成(x,y),(x+1,y),...,(x+n-1,y)。如何选择x 和y的值才能使士兵 们以最少的总移动步数排成一行。

计算使所有士兵排成一行需要的最少移动步数。

Format Input

第1 行是士兵数n,1≤n≤10000。接下来n 行是士兵的初始位置,每行2 个整数x 和y,-10000≤x, y≤10000。

Output

第1行中的数是士兵排成一行需要的最少移动步数。

Samples 输入数据

5
1 2
2 2
1 3
3 -2
3 3

输出数据

8

问题分析

士兵排对分为x方向和y方向 所以我们可以把x和y分开来思考 类似与输油管道问题

对于Y方向

设n个士兵的Y轴坐标分别为:Y1,Y2 …… …… Yn, 他们最后站在同一行上,设目标坐标为Y0,
则n个士兵最终在Y轴的需要移动的总的步数值为S1:
S1=|Y1-Y0|+|Y2-Y0|+ …… …… +|Yn-Y0|
结论:Y0取所有Yi的中间值时可以使得S1达到最小(这个结论可以证明)

对于X方向

(1)首先需要对所有士兵的X轴坐标值进行排序(为了方便就近移动)
(2)然后,按从左至右的顺序依次求出每个士兵所对应的“最终位置”(最优),所移动的步数总和就是X轴方向上需要移动的步数
设排序后n个士兵在X轴坐标为: X1’,X2’ …… …… Xn’
他们最终位置”的X轴坐标值为:X0,X0+1,X0+2 …… …… X0+(n-1)
则n个士兵最终X轴的需要移动的总的步数值为S2:
S2=|X1’-X0| + |X2’-(X0+1)|+… +|Xn’-(X0+n-1)|
经过变换
S2=|X1’-X0|+ |(X2’-1)-X0|+ …+|(Xn’-(n-1))-X0|
注意到公式的形式与Y轴方向上的考虑一样,同样是n个已知数分别减去一个待定数后取绝对值,然后求和
结论:求出x1’, x2’-1,… Xn’-(n-1) 的中位数,即求得X0值,最后算出最优解。

样例代码

#include

using namespace std;

int main(){

    int i,n,x;

    scanf("%d",&n);

    pair P[n];

    int a[n],b[n];

    for(i=0;i

        cin>>P[i].first>>P[i].second;

         a[i]=P[i].first;

         b[i]=P[i].second;

    }

    sort(b,b+n);

    int sum=0;

    x = b[n/2];

    for(i=0;i

        sum+=abs(b[i]-x);

    }

     sort(a,a+n);

    for(i=0;i

        a[i] = a[i]-i;

    }

    sort(a,a+n);

    x = a[n/2];

    for(i=0;i

        sum+=abs(a[i]-x);

    }

    printf("%d",sum);

}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5594717.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存