目錄
第1題第2題 總結
小強有n個養雞場,第i個養雞場初始有a[i]只小雞。與其他養雞場不同的是,他的養雞場每天增加k只小雞,小強每天結束都會在數量最多的養雞場裡賣掉一半的小雞,假如乙個養雞場有x隻雞,則賣出後只剩下x/2(向下取整)隻雞。問m天後小強的n個養雞場一共多少只小雞?最後幾分鐘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)
先暴力一手 例子能過 提交一直報錯
交完之後發現是沒有考慮輸入陣列為空的情況 導致分母會是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實現的
360 2017筆試程式題
題意 給出乙個3x3矩陣,判斷該矩陣是否關於 2,2 對稱。題解 include include using namespace std char g 10 10 int main if ok printf yes n else printf no n return 0 題意 給出n,求出1到n中由...
2020阿里實習4 22筆試
給定倆個整數n和m,n能拆分成m個數的和,對於任何乙個數字組合不能同時滿足以下兩個條件 任取乙個數字 1 該數的前乙個數比它大 2 該數的後乙個數比它大 問題是求出在這樣的條件下拆分n的最大組合數。例如 輸入5 3 輸出5示例解釋 error不滿足 解決思路 深搜 剪枝,複雜度o n m m 暫時沒...
筆試程式設計題 2012 3 22筆試
乙個筆試題目 n個人圍成乙個圈,第乙個人從1開始遞增報數,凡是報到3的倍數 包括3 時,該人退出,隨後的人接著再繼續報數,直到最後只剩下乙個人為止,求最後剩下的這個人在原對中的編號。思路 用陣列儲存n個人,開始陣列元素全部初始化為1,表示所有的人都在隊中,然後迴圈遍歷陣列,凡是遇到能整除3的位置的元...