描述
在一條數軸上有n家商店,它們的座標分別為 a[1]~a[n]。現在需要在數軸上建立一家貨倉,每天清晨,從貨倉到每家商店都要運送一車商品。為了提高效率,求把貨倉建在何處,可以使得貨倉到每家商店的距離之和最小。
輸入格式
第一行乙個整數n,第二行n個整數a[1]~a[n]。
輸出格式
乙個整數,表示距離之和的最小值。
樣例輸入
46 2 9 1
樣例輸出
12資料範圍與約定
對於100%的資料: n<=100000, a[i]<=1000000
這是一道裸的中位數題,但本人不想用快排,於是用了求第k小數的做法(不完全排序)。
方法1(快排):
#include
#include
#include
using
namespace std;
const
int n=
1e5+10;
int n,a[n]
,p;long
long ans;
#define g getchar()
voidqr(
int&x)
intmain()
方法2(第k小數):
#include
#include
#include
#include
#include
#define g getchar()
using
namespace std;
const
int n=
1e5+10;
voidqr(
int&x)
int a[n]
,n,k;
intrandom
(int x)
//取[0,x-1]中的數
intfind
(int l,
int r)
//查基準值排名
a[l]
=x;return l;
}int
dfs(
int l,
int r)
//返回第k小數
intmain()
這是運用分治的思想。
但是,可能大家會不理解find函式為什麼就能把[l,r]分成不大於基準值和不小於基準值的兩塊。不要急,且聽我娓娓道來~~
int
find
(int l,
int r)
//查基準值排名
a[l]
=x;return l;
}
首先,我們可以看出x就是選出的隨機基準值。
次之,我們可以用賦值環來解釋這樣做的正確性。
設第i次進入迴圈,執行第乙個賦值時的左右指
針分別為
li,r
i左右指標分別為l_i,r_i
左右指標分別
為li
,ri
,執行第二個賦值時的左右指
針分別為
li+1
,r
i左右指標分別為l_,r_i
左右指標分別
為li+
1,r
i,一共進入k次迴圈。
如果我們把賦值看作有向邊的話,很明顯可以想出,圖應該是這樣的:
l
1<−r
1<−l
2…
…<−l
k<−r
k +1 (<−表 示有向邊 )l_1<- \ r_1 <- l_2……<-l_k<-r_kl1 <−r 1<−l 2…… <−l k<−r k+1( <−表 示有向邊 )最後,我們把l 1l_1 l1的初值賦值給lk+ 1l_ lk+1 就相當於對(2k+1)個數進行了交換。同時也把[l,r]分成不大於基準值和不小於基準值的兩塊。 題意 在一條數軸上有 n nn 家商店,它們的座標分別為 a 1 a n a 1 sim a n a 1 a n 現在需要在數軸上建立一家貨倉,每天清晨,從貨倉到每家商店都要運送一車商品。為了提高效率,求把貨倉建在何處,可以使得貨倉到每家商店的距離之和最小。思路分析 把 a 1 a n a 1 si... 題目大意 在一條數軸上有n家商店,它們的座標分別為 a 1 a n 現在需要在數軸上建立一家貨倉,每天清晨,從貨倉到每家商店都要運送一車商品。為了提高效率,求把貨倉建在何處,可以使得貨倉到每家商店的距離之和最小。題目分析 中位數應用最經典的問題之一了,我們設應該將貨倉建立在座標x處,現在x左邊有p家...CH0501 貨倉選址
CH 0501 貨倉選址 中位數