刷題 阿里20200330筆試

2021-10-04 14:52:16 字數 1971 閱讀 5870

目錄

第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的位置的元...