## 0x02 <br> 2020 花中二模 <br> 題解 ---- ### 大綱 - pG - 簽到題之二 (Registration2) - pA - 競標 (Bidding) - pB - 畫作鑑定 (Art) - pC - 打工 (Work) - pD - 河內塔 (Hanoi) - pE - 小天使 (Angel) - pF - 塗鴉跳躍 (Jump) --- ### <font color="black"><b> pG. 簽到題之二 (Registration2) </b></font> ---- #### 簽到題之二 - 給定 $d$ $\small(0 \le d \le 10)$、$X$ $\small(1 \le X \le 1000)$、以及奇數 $N$ $\small(1 \le N \le 99)$。 - 輸出 $N$ 個數字 $A_1, A_2, \ldots, A_N$ 使: 1. $A_i \in [1, 10^9]$,對 $i = 1, 2, \ldots, N$ 2. $A_{i+1} - A_i \ge d$,對 $i = 1, 2, \ldots, N-1$ 3. $A_{(N+1)/2} = X$ 4. 最小化 $\sum A_i$ ---- #### 簽到題之二 -- Subtasks - $[10]$ $N = 1$ - $[25]$ $d = 0$ - $[65]$ 無額外限制 ---- #### 簽到題之二 -- Subtask 1 - 輸出 $X$ 就好。 - 送分的子題。 $\color{red}{\mbox{Wrong Answer}}\ 10/100$ ---- #### 簽到題之二 -- Subtask 2 - 中位數前的數字都放 $1$。 - 中位數後都放 $X$。 $\color{red}{\mbox{Wrong Answer}}\ 35/100$ ---- #### 簽到題之二 -- Solution - 中位數前的就依照 $A_1 = 1, A_i = A_{i-1} + d$ 去放。 - 中位數後的也類似 $A_{(N+1)/2} = X, A_i = A_{i-1} + d$。 - 如果放完發現不合法就代表無解。 - 實際上只會出現在 $A_{(N-1)/2}$ 跟 $A_{(N+1)/2}$ 之間 $\color{lime}{\mbox{Accepted}}\ 100/100$ --- ### <font color="black"><b> pA. 競標 (Bidding) </b></font> ---- #### 競標 - 有 $N$ 個人在競標,每個人有若干資金 $\small(\le 10^9)$。 - 給 $M$ 次喊價紀錄,請問最後得標者及成交價格。 - 合法的出價定義: - 要有足夠的錢 - 要比上一次喊的高 - 不能連續喊兩次(只有第一次會算合法) ---- #### 競標 -- Subtasks - $[10]$ 人名沒有空格、都是合法出價 - $[20]$ 人名沒有空格、價格一定越喊越高 - $[40]$ 人名沒有空格 - $[30]$ 人名可能有空格 ---- #### 競標 -- Solution - 用 `getline` 輸入人名 - 用 `map<string, int>` 存每個人的資金 - 剩下的好好判斷就行 $\color{lime}{\mbox{Accepted}}\ 100/100$ ---- #### 競標 -- 結論 - 這題主要是在考驗你們會不會使用 `map` - 不過因為範圍小,也可以直接存陣列暴力找 --- ### <font color="black"><b> pB. 畫作鑑定 (Art) </b></font> ---- #### 畫作鑑定 - 有 $N$ $\small(N \le 600)$ 個區間 $[\ell_i, r_i]$ $\small(1 \le \ell_i \le r_i \le 10^6)$ - 你要從中挑出 $N-K$ $\small(0 \le K \le 2)$ 個使畫作數量最小 ---- #### 畫作鑑定 -- Subtasks - $[28]$ $K = 0$ - $[25]$ $1 \le \ell_i \le r_i \le 15$ - $[47]$ 無額外限制 ---- #### 畫作鑑定 -- Subtask 1 - 每個區間都要選 - Greedy 的經典題 - 將區間按照右界排序,選最左邊的區間的右界當作第一幅畫的製造時間一定最好 - 把包含該點的區間丟掉,重複以上行為 $\color{red}{\mbox{Wrong Answer}}\ 28/100$ ---- #### 畫作鑑定 -- Subtask 2 - 時間點只有 $15$ 個 - 枚舉每個時間點是不是一幅畫的狀態 - 總共有 $2^{15} = 32\,768$ 個狀態 - 判斷能不能**至少**滿足 $N-K$ 位專家的意見 $\color{blue}{\mbox{Time Limit Exceeded}}\ 25/100$ ---- #### 畫作鑑定 -- Solution - 剛剛 greedy 的做法實際上可以在 $\mathcal{O}(N \lg N)$ 做完 - 放完一幅畫之後不用把重疊區間丟掉,只要 continue 就好 - 維護當前最後一幅畫的位置 ---- #### 畫作鑑定 -- Solution(續) - 因為 $K \le 2$ 很小,可以枚舉每一種假專家的組合 - 總共複雜度是 $\mathcal{O}\left(N \lg N + \binom{N}{K} \cdot N\right) = \mathcal{O}(N^{K+1}})$ $\color{lime}{\mbox{Accepted}}\ 100/100$ ---- #### 畫作鑑定 -- 結論 - 請嘗試證明看看剛剛的 greedy 為什麼會對 --- ### <font color="black"><b> pC. 打工 (Work) </b></font> ---- #### 打工 - 有一張 $N+1$ 點 $M$ 邊的連通圖 $\small(N, M \le 10^5)$ - 你一開始在點 $0$,也就是廚房,而其他點代表客人們 - 客人們分別想要 $a_i$ 盤菜,但你一次只能端至多 $K$ 盤 - 你最少需要進幾次廚房重新補貨? ---- #### 打工 -- Subtasks - $[\hphantom{0}6]$ $K = 1$ - $[11]$ $N = M$、圖是一條 $0-1-\cdots-N$ 的鏈 - $[40]$ $N = M$、圖是一棵樹,且所有 $a_i = 1$ - $[15]$ $N, M \le 2000$ - $[28]$ $N, M \le 100\,000$ ---- #### 打工 -- Subtask 1 - 輸出 $(\sum a_i) - 1$ - 這個子題的意義是讓你知道要 $-1$ - $6$ 分不拿白不拿 $\color{red}{\mbox{Wrong Answer}}\ 6/100$ ---- #### 打工 -- Subtask 2 - 輸出 $\lceil (\sum a_i) / K \rceil - 1$ - 這個子題的意義是讓你知道要上取整 - $11$ 分還是不拿白不拿 $\color{red}{\mbox{Wrong Answer}}\ 17/100$ ---- #### 打工 -- Solution - 對每個連通塊做一遍 DFS 找出 $a_i$ 總合 - 該連通塊的答案就是 $\lceil (\sum a_i) / K \rceil$ - 答案記得 $-1$ $\color{lime}{\mbox{Accepted}}\ 100/100$ ---- #### 打工 -- Solution 2 - 並査集 - 對每一條不包含廚房的邊都直接 `Union` - `Union` 的時候維護該「集團」的 $\sum a_i$ - 答案計算方法同上 $\color{lime}{\mbox{Accepted}}\ 100/100$ --- ### <font color="black"><b> pD. 河內塔 (Hanoi) </b></font> ---- #### 河內塔 - 輸出 $3$ 根柱子 $K$ $\small(1 \le K \le 9)$ 個圓盤的盒內塔最大步數 - 不能出現同樣的狀態 ---- #### 河內塔 -- Subtasks - $K = 1, 2, \ldots, 9$ - $\text{score} = [5, 5, 8, 8, 12, 12, 15, 15, 20]$ ---- #### 河內塔 -- Solution - 狀態數最多是 $3^K$ - 考慮每個圓盤在哪個柱子 - 遞迴的時候先往不是終點的狀態移就好 $\color{lime}{\mbox{Accepted}}\ 100/100$ ---- #### 河內塔 -- Code ```cpp= void recur(int n, int a, int b, int c) { if (n == k) return; recur(n+1, a, b, c); /// 上面的 a -> c cout << a << " " << b << "\n"; /// 最大的 a -> b recur(n+1, c, b, a); /// 上面的 c -> a cout << b << " " << c << "\n"; /// 最大的 b -> c recur(n+1, a, b, c); /// 上面的 a -> c } ``` - `recur(0, 1, 2, 3);` --- ### <font color="black"><b> pE. 小天使 (Angel) </b></font> ---- #### 小天使 - 給定 $N$ $\small(N \le 7000)$ 個數字 - 你要交換其中**任意**兩個數字 - 使得泡沫排序交換次數最少 ---- #### 小天使 -- Subtasks - $[11]$ $N \le 80$ - $[48]$ $N \le 1000$ - $[20]$ $1 \le a_i \le 2$ - $[21]$ $N \le 7000$ ---- #### 小天使 -- Subtask 1 - $N$ 那麼小,當然直接暴力R - 枚舉 $\binom{N}{2}$ 種交換方法 - 直接對它 bubble sort - 複雜度是 $\mathcal{O}(N^4)$ $\color{blue}{\mbox{Time Limit Exceeded}}\ 11/100$ ---- #### 小天使 -- Subtask 3 - 顯然交換第一個 $2$ 跟最後一個 $1$ 會最好 - 證明自己想想 (?) $\color{red}{\mbox{Wrong Answer}}\ 20/100$ ---- #### 小天使 -- Solution - 總共的交換次數就是數列裡滿足 $i < j$ 且 $a_i > a_j$ 的數量 - 可以想像把所有點 $(i, a_i)$ 都打到平面上 - 每次交換兩個元素時都會對答案貢獻一個矩形區間 ---- #### 小天使 -- Solution(續) - 用 `large[i][j]` 紀錄 $a_1, a_2, \ldots, a_{j-1}$ 有多少個數字 $> a_i$ - 用 `small[i][j]` 紀錄 $a_{j+1}, a_{j+2}, \ldots, a_N$ 有多少個數字 $< a_i$ - 這樣就可以在 $\mathcal{O}(N^2)$ 時間內預處理 - 並在 $\mathcal{O}(1)$ 時間回答每次交換的答案了! $\color{orange}{\mbox{Memory Limit Exceeded}}\ 59/100$ ---- #### 小天使 -- Solution(續) - 把 `large` 跟 `small` 存在一起 - 把陣列型態改成 `short` $\color{lime}{\mbox{Accepted}}\ 100/100$ --- ### <font color="black"><b> pF. 塗鴉跳躍 (Jump) </b></font> ---- #### 塗鴉跳躍 - 有 $N$ $\small(N \le 5 \cdot 10^5)$ 個踏板,分別在高度 $y_1, y_2, \ldots, y_N$ - 你現在在高度 $0$,目標是跳到高度為 $H$ $\small(H \le 10^9)$ 的終點 - 你每次都必須跳到更高的踏板上,且一次跳的高度至多為 $K$ $\small(1 \le K \le H)$ - 請問有幾種跳法可以到高度 $H$? - 兩種跳法相異若且唯若踩的踏板集合不同 - 輸出答案對 $10^9 + 7$ 取模 ---- #### 塗鴉跳躍 -- Subtasks - $[22]$ $N \le 20$、$H = 10^6$ - $[13]$ $N \le 1000$、$H = 10^6$ - $[\hphantom{0}7]$ $K = H = 10^6$、所有踏板高度皆相異 - $[11]$ $K = H = 10^6$ - $[35]$ $H = 10^6$ - $[12]$ $H \in \{10^6, 10^9\}$ ---- #### 塗鴉跳躍 -- Subtask 3 - 每個都可以選擇踩獲不踩 - 答案是 $2^N$ - 又一個送分子題 $\color{red}{\mbox{Wrong Answer}}\ 7/100$ ---- #### 塗鴉跳躍 -- Subtask 4 - 每個高度都可以選擇踩或不踩 - 同樣高度只能選一個 - 答案是 $\prod\limits_{1 \le i < H}{(c_i + 1)}$ - $c_i$ 是高度為 $i$ 的踏板數量 $\color{red}{\mbox{Wrong Answer}}\ 18/100$ ---- #### 塗鴉跳躍 -- Subtask 1 - 重要的只有高度,所以可以把踏板們先排序好 - $N$ 很小,可以枚舉所有情況 $\color{blue}{\mbox{Time Limit Exceeded}}\ 22/100$ ---- #### 塗鴉跳躍 -- Subtask 2 - 考慮使用 DP - 令 $\texttt{dp}[i]$ 代表走到第 $i$ 個踏板的方法數量 - 此處已將踏板們排序過 - 有 $\texttt{dp}[i] = \sum\limits_{y_j < y_i~且~y_j + K \ge y_i}{\texttt{dp}[j]}$ - 複雜度是 $\mathcal{O}(N^2)$ $\color{blue}{\mbox{Time Limit Exceeded}}\ 35/100$ ---- #### 塗鴉跳躍 -- Solution - 上述 DP 式的轉移條件: - $y_j < y_i$ 且 $y_j + K \ge y_i$ - 相當於是 $y_j \in [y_i - K, y_i)$ - 因為 $y_j$ 是按照順序排好的,所以可以轉移的區間一定是連續的 - 二分搜最小跟最大的 $j$ ---- #### 塗鴉跳躍 -- Solution(續) - 要怎麼計算區間的 $\sum\limits_{k=j}^{i-1}\texttt{dp}[k]$? - ~~我會線段樹/BIT~~ 差分跟前綴和! - 令 $\texttt{sdp}[i] = \sum\limits_{k=1}^{i}{\texttt{dp}[k]}$ - 那麼 $\sum\limits_{k=j}^{i-1}\texttt{dp}[k]$ 就變成 $\texttt{sdp}[i-1] - \texttt{sdp}[j-1]$ - 這樣 DP 的複雜度就是 $\mathcal{O}(N \lg N)$ $\color{lime}{\mbox{Accepted}}\ 100/100$ ---- #### 塗鴉跳躍 -- Solution 2 - 每次當 $i$ 增加的時候,轉移區間左右界 $j_\ell$、$j_r$ 也會增加(或不動) - 左右界移動的次數只會是 $\mathcal{O}(N)$ - 使用 two-pointer 維護左右界同時計算區間 $\texttt{dp}$ 值之和 - 這樣 DP 的複雜度會降到 $\mathcal{O}(N)$! $\color{lime}{\mbox{Accepted}}\ 100/100$ --- ### 總覽 - pA - 送分題 - pB - 枚舉 + greedy - pC - DFS 或 並査集 - pD - 遞迴 - pE - 觀察 - pF - DP + 二分搜 或 two-pointer - pG - 送分題 ---- ### 總覽 **以下是只用「暴力」實作可以得到的分數** - pA:$\color{lime}{100}$ - pB:$\color{lime}{28}\ /\ \color{lime}{25}\ /\ \color{red}{47}$ - pC:$\color{lime}{6}\ /\ \color{lime}{11}\ /\ \color{red}{40}\ /\ \color{red}{15}\ /\ \color{red}{28}$ - pD:$\color{red}{0}$ 到 $\color{lime}{100}$ - pE:$\color{lime}{11}\ /\ \color{red}{48}\ /\ \color{lime}{20}\ /\ \color{red}{21}$ - pF:$\color{lime}{22}\ /\ \color{red}{13}\ /\ \color{lime}{7}\ /\ \color{lime}{11}\ /\ \color{red}{35}\ /\ \color{red}{12}$ - pG:$\color{lime}{100}$ - 總共是 $100 + 53 + 17 + [0, 100] + 31 + 40 + 100 = [341, 441]$ ---- ![](https://i.imgur.com/TGWJucQ.jpg) --- ### 謝謝收看 東西都放在[這裡](https://drive.google.com/drive/folders/10puAreRd1_sTSBsTvq3leNTDYeYntXvt)了
{"metaMigratedAt":"2023-06-17T12:50:01.167Z","metaMigratedFrom":"YAML","title":"0x02 2020 花中二模 題解","breaks":true,"slideOptions":"{\"theme\":\"solarized\",\"transition\":\"fade\",\"controls\":false}","contributors":"[{\"id\":\"e573a1ba-d69b-44a7-a0d5-9d817fb786cc\",\"add\":8634,\"del\":279}]"}
    614 views