3625 codevs 士兵站隊問題 中位數的妙用

2022-02-13 16:24:17 字數 1782 閱讀 6254

士兵站隊問題

題目描述 description

在乙個劃分成網格的操場上,n個士兵散亂地站在網格點上。網格點用整數座標(x,y)表示。士兵們可以沿網格邊往上、下、左、右移動一步,但在同一時刻任一網格點上只能有一名士兵。按照軍官的命令,士兵們要整齊地列成乙個水平佇列,即排列成(x,y),(x+1,y),…,(x+n-1,y)。如何選擇x和y的值才能使士兵們以最少的總移動步數排成一行。程式設計計算使所有士兵排成一行需要的最少移動步數。

輸入描述 input description

第1行是士兵數n,1≤n≤10000。接下來n行是士兵的初始位置,每行有2個整數x和y,-10000≤x,y≤10000。

輸出描述 output description

乙個資料,即士兵排成一行需要的最少移動步數。

樣例輸入 sample input

1 22 2

1 33 -2

3 3樣例輸出 sample output

資料範圍及提示 data size & hint

-10000≤x,y≤10000

**如下:

#include

#include

#include

#include

#include

using namespace std;

int x[10009],y[10009];

int main()

{int n,sx=0,sy=0;

scanf("%d",&n);

for(int i=0;i思路解析:

士兵站隊,要站在同一排,且乙個點只有乙個士兵。

士兵要先統一y軸,即士兵移動後縱座標相等,然後移動x軸使其分散開;

一、統一y軸的最優方法

設目標座標為m,即n個士兵最終需要移動到的y軸的座標值為m

n個士兵的y軸座標分別為:

y0,y1,y2 …… …… yn-1

則最優步數s=|y0-m|+|y1-m|+|y2-m|+ …… …… +|yn-1-m|;

那麼m取何數值時,會發現當m為縱座標排序後的中位數時s最小。接下來給予證明

|a|-|b|≤|a+(或者是相減)b|≤|a+b|≤|a|+|b|(不做證明了)

例如(假設有兩個士兵,我們從簡單的開始討論)

則 s=|y0-m|+|y1-m|,可轉換為 s=|m-y0|+|y1-m|;

兩個絕對值相加,我們可以用開始的公式消去m;

則 |m-y0|+|y1-m| ≥ |y1-y0|;

那麼何時 |m-y0|+|y1-m| = |y1-y0|取得最小呢?

可發現 當絕對值號中符號相同時 可取得最小,令其都大於0

則            y0可想 當m在兩個士兵縱座標之間時 無論怎麼移動 兩個士兵移動的距離和 都是兩個士兵之間的距離

所以s=|y0-m|+|y1-m|+|y2-m|+ …… …… +|yn-1-m|對於這個公式使前一半絕對值號內交換位置,都令其大於零,消去m,最後會發現m就是士兵排序之後縱座標的中位數

二、同統一y軸的方法

設,士兵需要移動到的「最終位置」的x軸座標值為:k,k+1,k+2 …… …… k+(n-1)

則所求最優步數s=|x0-k|+|x1- (k+1) |+|x2-(k+2)|+ …… +|xn-1-(k+(n-1))|

經過變形s=|x0-k|+|(x1-1)-k|+|(x2-2)-k|+ …… …… +|(xn-1-(n-1))-k|

k的取值同理是其中位數;

注意:x軸先從小到大排序之後,在依次減0-- n-1,再排序,再找中位數。

士兵站隊問題

問題描述 在乙個劃分成網格的操場上,n個士兵散亂地站在網格點上,網格點由整數座標 x,y 表示。士兵們可以沿網格邊上 下 左 右移動一步,但在同一時刻任一網點上只能有一名士兵。按照軍官的命令,士兵們要整齊地列成乙個水平佇列,即排列成 x,y x 1,y x n,y 如何選擇x和y的值才能使士兵們以最...

士兵站隊問題

題解 首先已知縱向移動可以直接通過求中位數得到 那麼問題就是橫方向移動了 我們假設第一位士兵站的位置是k,因為x從x1開始,那麼我們假設成起始位置為k 1吧 不懂接著看完你就懂了 那麼 第二位士兵的位置是 k 2,接著是k 3,k 4,k n 所以,士兵橫向 即平行於y軸方向 移動的距離為 x1 k...

9209 士兵站隊問題

time limit 10 second memory limit 2 mb 問題描述 在乙個劃分成網格的操場上,n個士兵散亂地站在網格點上。網格點由整數座標 x,y 表示。士兵們可以沿網格邊上 下 左 右移動一步,但在同一時刻任一網格點上只能有一名士兵。按照軍官的命令,士兵們要整齊地列成乙個水平佇...