1. 程式人生 > >愛奇藝2018.9.28筆試 散散的樹

愛奇藝2018.9.28筆試 散散的樹

題目描述

在這裡插入圖片描述 輸入: 5 20 4 42 40 26 46 輸出: 36

鋸子必須同時砍樹; 從樹頂到鋸子這段距離被砍下來當成木頭,從樹根到鋸子這段距離留下原地。 問鋸子最高可以多高,但其實要剛好使砍下來的木頭的總長為m,其實就只有一種鋸子的高度能滿足。

排序後遍歷

n,m = map(int,input().split())
li = list(map(int,input().split()))

li = sorted(li,reverse=True)#降序排序
li.append(0)#這樣就能砍到最矮的樹

Times = 1#倍數
result = 0#已經砍下的木頭的總長

if len(li)
== 1:#只有一棵樹 print(li[0] - m) elif len(li) > 1: for i in range(1,len(li)): temp = (li[i-1] - li[i]) * Times tempResult = result + temp if tempResult >= m: if (m-result)%Times == 0: last = (m-result)//Times else: last =
(m-result)/Times print(li[i-1]-last) break else: result = tempResult Times += 1

在這裡插入圖片描述 如上圖所示,以樣例輸入為例。 排降序後,黑色數字就是5顆樹。 紅色數字代表相鄰兩棵樹之間的高度差,藍色數字代表在這個區間內可以砍到幾棵樹。 比如,如果鋸子高度為42,那麼只能鋸下長度為4的木頭,而這樣的木頭只有1根。而如果鋸子高度為40,那麼除了之前鋸下的4*1的木頭,還有2*2的木頭可以鋸下。 黃色數字,說明了這個累加的過程。 由於8<20<50,所以鋸子的高度肯定是在[40,26]這個區間內。

演算法的思想是: 每次迴圈中,考慮鋸子的高度為li[i],那麼此時鋸子能鋸到從li[0]到li[i-1]這幾棵樹(li[i]這棵樹剛好鋸不到),然後算出當前鋸子能砍下的木頭的總長: 1.如果這個總長還是小於m,那麼i++,繼續迴圈。 2.如果這個總長大於等於m,那麼迴圈停止。然後根據當前的i,計算鋸子的高度。具體地來說:使用上一次迴圈i-1用的鋸子所能砍下的樹的總長resultm-result就是剩餘需要砍下來的木頭長度。Times就是當前能砍到幾棵樹。

前面的每次迴圈,代表區間[ li[i-1] , li[i] ]的樹都被完全砍掉了。 最後一次迴圈i中,代表區間[ li[i-1] , li[i] ]的樹不是被完全砍掉的。因此用m-result除以Times就是當前區間需要砍掉的每根木頭的長度lastlast是可能為小數的,需要注意。 最終結果便是,li[i-1]-last