前往
大廳
主題

ZeroJudge - c364: 我鄙視你 解題心得

Not In My Back Yard | 2021-08-09 00:00:06 | 巴幣 2 | 人氣 356

題目連結:


題目大意:
輸入第一列給定一正整數 N(1 ≦ N ≦ 10 ^ 6),代表有 N 個同學排成一列。接著一列給定 N 個正整數(皆介於 1 ~ 10 ^ 9),代表每位同學的身高。

每位同學各自將會往左以及往右鄙視所有身高比他身高矮的同學,直到碰到不矮於他的身高之同學為止。

請輸出每位同學鄙視的同學們之身高總和。



範例輸入:
5
140 150 170 180 160


範例輸出:
0
140
290
620
0


解題思維:
先討論每個同學只「往左」鄙視到不矮於他的同學之情況:
我們可以維護一個堆疊 S(Stack),其從底部到堆疊頂端的元素保持著遞減之狀態,但是裡面的數字要大越好。而每個元素儲存著同學的編號(這邊定為從左至右編號為 1 ~ N),以及該位同學之身高這兩個資訊。

最一開始,我們將 (0, 2000000000) 這個資訊放到 S 的頂端,作為「界線」(因為不會有人身高值比 2000000000 大)。

接著從左至右掃過每位同學的身高 H。我們先判斷堆疊頂端的元素之身高是否 < H。如果是,則代表本同學的鄙視同學區間可以從 (此同學編號 - 堆疊頂端的同學編號) 繼續往左延伸,因此我們將 S 頂端移除掉(因為這個同學不再扮演任何重要的判斷用之角色)。重複此步驟直到堆疊頂端之身高 ≧ H。

此時我們便無法再繼續鄙視下去,因此此位同學將會鄙視所求為此同學(不含) ~ 堆疊頂端的同學(不含)之間所有的同學。而我們可以根據前綴和(Prefix Sums)之概念求出這個區間中的同學之身高總和(參見這題)。最後我們將這位同學的編號以及身高放到 S 中,並繼續到下一個學生(如果有的話)。



而「往右」鄙視也是與上同理。從左至右和由右到左各掃一次後,便可以求出每位同學鄙視之同學身高總和。不過因為身高值可以到 10 ^ 9,所以對 C++ 等等語言需要宣告成長整數型態來儲存總和以免加總時溢位。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

LOVe高橋李依
題目名字很有趣
為什麼會有鄙視的題目啦xdd
2021-08-09 04:04:48

更多創作