目錄
第1題
小強有n個養雞場,第i個養雞場初始有a[i]只小雞。與其他養雞場不同的是,他的養雞場每天增加k只小雞,小強每天結束都會在數量最多的養雞場裏賣掉一半的小雞,假如一個養雞場有x只雞,則賣出後只剩下x/2(向下取整)只雞。問m天后小強的n個養雞場一共多少隻小雞?
-
輸入
第一行輸入三個int類型n,m,k(1 <= n,m,k <= 10^6)
第二行輸入n個正整數,表示n個養雞場初始雞的個數
-
輸出
輸出一個整數表示雞的總數
-
示例
輸入:
3 3 100
100 200 400
輸出:
925
最後幾分鐘A了,很慌張。要點:
0 每天要選最大值 -> 數據結構使用大頂堆(優先隊列)
1 不能去更新隊列裏面的每個數值(否則必tle),隊列裏每個數都與實際值相差了i*k (i爲天數)
2 每天的最大值出隊後 賣掉一半 入隊的時候數值計算公式很關鍵:(max_-i*k)//2
計算公式是怎麼來的呢?
出隊得到假數值裏的max -> 恢復到真數據 -> 減少一半 -> 再減去偏移量(恢復到假數值)
即 ( max_+i*k )//2 - k*i 變換後得到 ( max_ - i*k )//2
畫個圖解釋一下 【隊列裏每個數都與實際值相差了i*k (i爲天數)】
在實現上,由於python只有小頂堆(headq/queue.PriorityQueue),所以去負數來實現選擇最大值 即每次入隊時取負、 ( max_ - i*k )//2 裏的 - i*k 變成 + i*k
import sys
line = sys.stdin.readline().strip()
n, m, k = map(int, line.split())
line = sys.stdin.readline().strip()
a = list(map(int, line.split()))
from queue import PriorityQueue
q = PriorityQueue()
for i in a:
q.put(-i) #入隊時都取負
for i in range(1, m + 1):
max_ = q.get()
tmp= (max_ + k * i) // 2 # - i*k 變成 + i*k
q.put(tmp)
print(-sum(q.queue) + n * m * k) #隊列裏n個假數據都和真數據相差了m*k
長度爲n的優先隊列,每次維護的複雜度是logn;一共取了m次最大值、修改堆 故時間複雜度爲O(mlogn)
第2題
先暴力一手 例子能過 提交一直報錯
交完之後發現是沒有考慮輸入數組爲空的情況 導致分母會是0 不過照這次筆試的尿性 就算考慮了八成也是0分 這個題暫時沒怎麼想
題目描述:
總結
真是慌了神了 因爲習慣是每道題先無腦暴力試水 然後兩道題一直都是0分 搞得我一直以爲自己哪裏寫錯了 光輸入改了好幾次 最後還是例子沒錯但提交雙0 心態崩了
緩一緩 從暴力想到了幾次優化:1使用優先隊列 減少每次取max的複雜度 2不能每天都更改隊列中所有數值,隊列裏每個數都與實際值相差了i*k 趕緊根據150=400-250寫出了公式max_-(max_+i*k)//2 變換後和前面寫的是一致的 最後幾分鐘A了 幸虧公式一找就找對了 要不然gg 與阿里無緣了 連面試都進不去 可真是太菜太丟人了
tips:
python中headq和queue.PriorityQueue的異同?
1 PriorityQueue保證線程安全 heapq 8星
2 PriorityQueue是對heapq的部分封裝 也就是說PriorityQueue就用heapq實現的
參考資料:
https://www.nowcoder.com/discuss/396281?type=1