題目描述
shopee物流會有很多個中轉站。在選址的過程中,會選擇離使用者最近的地方建乙個物流中轉站。
假設給你乙個二維平面網格,每個格仔是房子則為1,或者是空地則為0。找到乙個空地修建乙個物流中轉站,使得這個物流中轉站到所有的房子的距離之和最小。 能修建,則返回最小的距離和。如果無法修建,則返回 -1。
若範圍限制在100*100以內的網格,如何計算出最小的距離和?
當平面網格非常大的情況下,如何避免不必要的計算?
輸入描述:
4
0 1 1 0
1 1 0 1
0 0 1 0
0 0 0 0
先輸入方陣階數,然後逐行輸入房子和空地的資料,以空格分隔。
輸出描述:
8
能修建,則返回最小的距離和。如果無法修建,則返回 -1。
示例1輸入
4
0 1 1 0
1 1 0 1
0 0 1 0
0 0 0 0
輸出
8
示例2
輸入
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
輸出
-1
暴力很顯然是最不可取的,遍歷計算所有房子到某一格的距離的時候都要內嵌兩層,很耗時間
所以我們進行觀察與思考,發現,假設所有房子到(0,0)的距離為s,那麼當中轉站在(0,0)的時候,距離就是s(暫時不考慮(0,0)是否有房子)
如圖,八芒星即代表中轉站
當中轉站移動到(i,j)後,對於i行之前的第k行來說,其到中轉站的距離為-k+j-k=>j-2k
對於i行之後的所有行來說(包括第i行),他們到新中轉站的距離都減少i (大於i的行都不在需要到達第0行)
所以移動後的距離和為
而這個式子對於列來說也是成立的
因此,我們只需要提前求出s,以及每行每列的房子數,然後遍歷一次陣列,並在每次更新的時候保留較小值作為結果便可以了。
def
solution
(n,arr)
: row=[0
for i in
range
(n)]
#每**子數
col=[0
for i in
range
(n)]
#每列房子數
res=-1
s=0#距離
#到0,0距離
for i in
range
(n):
for j in
range
(n):
if arr[i]
[j]==1:
s+=i+j
row[i]+=1
col[j]+=1
for i in
range
(n):
for j in
range
(n):
if arr[i]
[j]==1:
continue
s=sfor r in
range
(n):
if r
s=s+
(j-2
*r)*col[r]
elif r>=j:
s=s-j*col[r]
if r
s=s+
(i-2
*r)*row[r]
elif r>=i:
s=s-i*row[r]
if res==-1
: res=s
else
: res=
min(res,s)
return res
if __name__==
'__main__'
: n=
int(
input()
) arr=
for i in
range
(n):
list
(map
(int
,input()
.strip(
).split())
))print
(solution(n,arr)
)
牛客網中Spring的理解
spring官方文件 依賴注入就是通過容器去管理物件,而不是物件本身去管理 1 spring中對ioc的理解 所謂 控制反轉 是指控制權由應用 轉到外部容器,即控制權的轉移 ioc將控制建立的職責搬進了框架中,從應用 脫離開來 使用spring的ioc容器時只需指出元件需要的物件,在執行時sprin...
牛客網 陣列中的逆序對
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。即輸出p 1000000007 最直接的想法,是兩個for迴圈巢狀,求解所有的逆序對,但是複雜度太高。後參考陣列中的逆序對,利用了...
陣列中的逆序對 牛客網
題意理解 給定乙個陣列,求逆序對的個數,所謂逆序對是指i j,但是aj ai.問題分析 歸併排序,複雜度降到o nlgn 細節1 歸併過程是先排序子陣列內部,再排序子陣列之間。細節2 排序子陣列內部,需要用到額外的空間,用輔助陣列作原始陣列,用當前陣列儲存一趟歸併的結果。細節3 排序子陣列之間的方法...