1. 程式人生 > 實用技巧 >1.9 貨倉選址問題——Python

1.9 貨倉選址問題——Python

題目描述

在一條數軸上有 N 家商店,它們的座標分別為 A1~AN。

現在需要在數軸上建立一家貨倉,每天清晨,從貨倉到每家商店都要運送一車商品。

為了提高效率,求把貨倉建在何處,可以使得貨倉到每家商店的距離之和最小。

輸入格式

第一行輸入整數N。

第二行N個整數A1~AN。

輸出格式

輸出一個整數,表示距離之和的最小值。

資料範圍

1≤N≤100000,
0≤Ai≤40000

輸入樣例

4
6 2 9 1

輸出樣例

12

題目分析

這是一道非常基礎的演算法題,要求一個貨倉到每家商店的最短距離,我的思路如下:

1.我們要找一個倉庫,他們在一條路線上

2.如果是二維的,我們就要一個一個進行判斷計算,因為他要求所有的最短距離。但是這道題是一維,所以首先需要求出貨倉的座標

3. 不難分析,當貨倉處於所有商店最中間的位置時,到每家商戶的距離將會最近,即貨倉處於的位置應該是商店座標的中位數。

假設區間[a,b]的距離;是n那麼如果貨倉x選在區間[a,b]的任一位置的話,s=n;如果選在區間[a,b]之外的話,s>n。 因此貨倉應選在兩個點之間,推廣到n個商店的情況的話,貨倉應該選在最中間的兩個點之間,此時的s-定是最小的(可以用反證法證明)。當商店個數是奇數時,中位數只有一個; 當個數是偶數時,中位數有兩個,此時可以取兩個中位數的平均值,或是直接取整**

4. 確定了貨倉的座標之後,就可以通過將貨倉的座標和每個商店的座標相減取絕對值再加和,得到貨倉到每家商店的最短距離

原始碼

 1 # import numpy as np
 2 
 3 n = int(input())
 4 # 兩種輸入方式
 5 # nums = list(map(int, input().split()))
 6 arr = input("")
 7 nums = [int(i) for i in arr.split()]
 8 
 9 # 對輸入的陣列進行排序
10 nums.sort()
11 
12 # 兩種求中位數方式
13 address = nums[n >> 1]
14 # address = np.median(nums)
15 
16 res = 0
17
for num in nums: 18 res += abs(num - address) 19 print(res)

注意問題

1. 一維陣列的輸入方式:

nums = list(map(int, input().split()))

或者是:

arr = input("")
nums = [int(i) for i in arr.split()]

2. 求中位數的方式:

① 可以通過匯入numpy包,引用其中的median()函式直接求得中位數。

import numpy as np

nums = [6, 5, 8, 2]
address = np.median(nums)

② 也可以通過移位運算子: >> ,移位運算子針對二進位制數進行左移或右移,即移動的單位是二的冪次方。假設 n = 8,其二進位制為 0000 1000 ,則 n >> 1為 n 向右移2^1,即 0000 0100,此時得到的結果是4,可以直接取得中位數。

address = nums[n >> 1]