CH0501 貨倉選址(第k小數)

2021-09-20 18:41:15 字數 2102 閱讀 3326

描述

在一條數軸上有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]分成不大於基準值和不小於基準值的兩塊。

CH0501 貨倉選址

題意 在一條數軸上有 n nn 家商店,它們的座標分別為 a 1 a n a 1 sim a n a 1 a n 現在需要在數軸上建立一家貨倉,每天清晨,從貨倉到每家商店都要運送一車商品。為了提高效率,求把貨倉建在何處,可以使得貨倉到每家商店的距離之和最小。思路分析 把 a 1 a n a 1 si...

CH 0501 貨倉選址 中位數

題目大意 在一條數軸上有n家商店,它們的座標分別為 a 1 a n 現在需要在數軸上建立一家貨倉,每天清晨,從貨倉到每家商店都要運送一車商品。為了提高效率,求把貨倉建在何處,可以使得貨倉到每家商店的距離之和最小。題目分析 中位數應用最經典的問題之一了,我們設應該將貨倉建立在座標x處,現在x左邊有p家...