【P1889】SOLDIERS (中位數)
阿新 • • 發佈:2018-12-15
題目描述
在一個劃分成網格的操場上, n個士兵散亂地站在網格點上。由整數 座標 (x,y) 表示。士兵們可以沿網格邊上、下左右移動一步,但在同時刻任一網格點上只能有名士兵。按照軍官的命令,們要整齊地列成個水平佇列,即排成 佇列,即排成 (x,y),(x+1,y), …,(x+n -1,y) 。如何選擇 x 和y的值才能使 士兵們以最少的總移動步數排成一列。
輸入輸出格式
輸入格式:
檔案的第 1 行是士兵數 n,1≤n≤10000 。接下來 n 行是士兵的初始位置, 每行 2 個整數 x 和y,-10000 ≤x,y≤10000 。
輸出格式:
檔案中 只有一個整 數是士兵排成一行需要的最少移動步。
輸入輸出樣例
5 1 2 2 2 1 3 3 -2 3 3輸出樣例1:
8輸入樣例2:
7
2 3
3 4
4 5
1 10
5 21
3 12
10 5
37
解析:
中位數的拓展題,需要從橫縱座標兩邊考慮,但是這個橫縱好像不是我理解的那種......
為了使座標形成(x,y),(x+1,y),(x+2,y)......(x+n-1,y),就可以使每個Xi都向左移i個單位,在最理想的狀態下每個(Xi-i)就應該在同一個位置。然後我們需要思考:沒有達到同一個位置怎麼辦?顯然就應該取一個值使所有X值都向它移,於是中位數自然而然又出來了!
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; int ans=0,n,x[10005],y[10005]; int main() { 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); int mid1=y[(n+1)/2]; for(int i=1;i<=n;i++) { x[i]-=i; } sort(x+1,x+n+1); int mid2=x[(n+1)/2]; for(int i=1;i<=n;i++) { ans+=abs(mid1-y[i]); ans+=abs(mid2-x[i]); } printf("%d",ans); }