一場 ICPC,寫幾個題的題解。
A
用 \(15\) 減去四個輸入即可。
D
圖論題,考完發現都寫的是 dijkstra,但是我寫的是 BFS。
模板是基礎,然後對於每個狀態記錄現在的方向和朝這個方向連續走了多少次,顯然,當次數等於 \(4\) 時,你需要換方向,如果要沿同一防線繼續走,就需要後退一步再前進兩步。
這時就有 hack 來卡我了,如果按照這種方式連續朝同一方向前進,那麼這樣後退再前進的花費會是 \(2\),也就是消耗了一次向前走的機會。但是,如果現在的左右(或上下)有空格子,你可以向別的方向換一下,再朝原方向前進,這樣花費是 \(1\)。舉個例子:
S.........T
...........
這樣的路,你可以直接直線行走,也可以向前走兩格再向下移動,再回來,是更優的。
有個細節,就是優先佇列中有位置相同,答案相同,但是方向來源不同的點,為了保證正確性,你需要把符合這些條件的所有點全部跑出來,而不是隻取第一個,有這樣一個 hack 資料,找到了我在賽時錯誤(來自 Baiyj):
5 18
S................T
.################.
.################.
..##....##....##..
..................
E
構造題。首先,一定有一個長度為 \(3\) 的序列滿足條件,因為要滿足平均數是 \(a\),中位數是 \(b\),設三個數是 \(x,y,z\) 其中 \(x<y<z\),那麼有
選定一個 \(x\) 就可以了,注意有可能 \(x,z\) 都小於 \(y\),判斷一下就會。
M
貪心題。
題目給這定兩個函式:
-
字首排序函式:選擇 \(\forall i\in [1,n]\),把區間 \([1,i]\) 排序,花費代價是 \(i^2\);
-
字尾排序函式:選擇 \(\forall i \in [1,n]\),把區間 \([n-i+1,n]\) 排序,花費代價是 \(i^2\)。
給出一個序列,問你把它排成升序序列的最小花費。
觀察可以發現,一定是一次字首一次字尾,並且排序的次數一定不大於 \(2\)。
證明:
考慮先前已經經過了一次字首排序,再進行一次字首排序一定會涉及前面已經有序的區間,會使得答案不優。因為我們答案更優一定要讓越少的地方被多次排序。
那麼策略就很明顯了,首先,如果選定一個位置 \(i\) 做字首排序,一定可以找到另一個位置 \(j\) 做字尾排序,使得序列有序。易得極端情況下 \(j\) 取 \(1\) 一定可以滿足。先字尾排序再字首排序同理。
那麼,我們如何找到這個位置呢?
以先字首再字尾為例,假設排完字首,前 \(k\) 小的數已經到前 \(k\) 個位置,那麼第二次排序一定是從 \(k+1\) 開始排的。也就是說,若當前排好的序列中有 \(k\) 個前 \(k\) 小(或大)的數,那麼第二次排序的位置就是 \(k+1\)。
預處理很簡單,用優先佇列即可。
有一個小細節,就的形如 321456897
的序列,先給 \(3\) 字首排序,你會發現第二次排序的位置是 \(7\),也就是有可能有更多的有序位置在後面(或前面)出現,特判一下就好。