本題為 Two Steps 題,限用 C++ 作答。你可以在這裡找到範例實作以及範例評分程式,詳細注意事項以及常見問題請參考 Hints。
為配合 TIOJ 格式,本題與 YTP 中使用的格式有些不同。
Alice 想要跟 Bob 用神秘語言溝通,這個神秘語言有 $n$ 種字元,第 $i + 1$ 常見字元出現的頻率是 $a[i]$。
他們需要找到一組可以唯一解碼的位元編碼方法 ${h[0], h[1], \ldots, h[n-1]}$,滿足任意字元的編碼不能是另一種字元的前綴。為了在最少的位元數編碼訊息,他們需要最小化
$$ \sum_{i=0}^  {n-1} |h[i]| \cdot a[i]。$$
不過字元編碼的出現次數在 Alice 手上。Alice 可以傳給 Bob 一個訊息,請你幫幫他們找到編碼的方法。

詳細細節與評分方式請見後續段落。
你的程式需要在一開始使用前置處理器引入 lib0970.h,詳細請參考範例實作。
你需要完成以下的兩個函式,詳細執行流程請參考後面的內容:
std::string Alice(int n, int L, std::vector<int> a);
Alice 會被呼叫恰 $1$ 次。Alice 傳送給 Bob 訊息的最大長度0, 1 字元組成的字串,且字串長度不得超過 $L$。std::vector<std::string> Bob(std::string s);
Bob 會被呼叫恰 $1$ 次。Alice(n, L, a) 回傳的字串。你回傳的 ${h[0], h[1], \ldots, h[n-1]}$ 需要同時滿足以下條件:
如果任意一個條件沒有被滿足,你的程式會被判斷為 Wrong Answer 並且獲得 0 分,否則,你的程式將依照 Scoring 中的敘述評分。
而評測系統會用以下執行的過程:
Alice(),並將回傳的字串 $s$ 儲存起來。Alice() 回傳的字串 $s$ 為引數呼叫 $1$ 次 Bob(),如果回傳的結果符合上述所有條件,則會視為 Accepted。
 
| 評測程式端 | 參賽者程式端 | 
|---|---|
| 系統第一次執行參賽者的程式。 | |
呼叫 Alice(5, 512, [11, 8, 7, 7, 3])。 |     |
回傳 "111111111110111111110111111101111111011100"。 |   |
| 系統第二次執行參賽者的程式。 | |
呼叫 Bob("111111111110111111110111111101111111011100")。 |   |
| 回傳 $[\texttt{01}, \texttt{10}, \texttt{001}, \texttt{11}, \texttt{000}]$。 | 
這時候評分程式會檢查:
$$\sum_{i=0}^  {n-1} |h[i]| \cdot a[i] = 2 \cdot 11 + 2 \cdot 8 + 3 \cdot 7 + 2 \cdot 7 + 3 \cdot 3 = 82$$,這是最小的可能之一。
另一個被判斷為 Accepted 的範例互動狀況如下:
 
| 評測程式端 | 參賽者程式端 | 
|---|---|
| 系統第一次執行參賽者的程式。 | |
呼叫 Alice(64, 512, [1, 1, ..., 1])。 |     |
回傳 ""(空字串)。 |   |
| 系統第二次執行參賽者的程式。 | |
呼叫 Bob("")。 |   |
| 回傳 $[\texttt{000000}, \texttt{000001}, \ldots, \texttt{111111}]$。 | 
這時候評分程式會檢查:
$$\sum_{i=0}^  {n-1} |h[i]| \cdot a[i] = 6 \cdot 64 = 384$$,這是最小的可能之一。
對於子任務 4,令 $J = |s|$ 為你在 Alice 子程式所回傳字串的最大長度,你在本子任務的得分依下表計算:
| $J$ | $512$ | $448$ | $384$ | $320$ | $256$ | $192$ | $128$ | $64$ | $60$ | $0$ | 
| 分數 | $1$ | $2$ | $3.5$ | $5.5$ | $8$ | $11$ | $15$ | $20$ | $22$ | $22$ | 
你的得分將由上表透過線性內插計算得到。舉例來說,當 $J = 267$ 時,你的得分為
$$
8 + \frac{5.5 - 8}{320 - 256} \cdot (267 - 256) \approx 7.57
$$
分。
範例評分程式以下列方式輸入:
範例評分程式的輸出格式如下:
[Alice] s = "${s}"[Bob] h[i] = "${h[i]}"The length of s is ${|s|} and the cost is ${cost}.
如果評分程式發現錯誤,則輸出格式如下:
Judge Error [1]:輸入的 ${a[0], a[1], \ldots, a[n-1]}$ 沒有按照從大到小排序。Judge Error [2]:輸入的 $a[0] \ge 2^  {22}$。Judge Error [3]:輸入的 $a[n-1] \le 0$。Wrong Answer [4]:Alice 傳給 Bob 的字串長度超過 $L$。Wrong Answer [5]:Alice 傳給 Bob 的字串內容包含 $\texttt{0}$ 或 $\texttt{1}$ 以外的字元。Wrong Answer [6]:Bob 構造的 $H$ 長度不為 $n$。Wrong Answer [7]:Bob 構造的 $H$ 包含 $\texttt{0}$ 或 $\texttt{1}$ 以外的字元。Wrong Answer [8]:Bob 構造的 $H$ 存在 $i \ne j$ 滿足 $h[i]$ 是 $h[j]$ 的前綴。請注意,範例評分程式不會檢查你的 $\text{cost}$ 是不是最小值。
5 512 11 8 7 7 3
[Alice] s = "111111111110111111110111111101111111011100" [Bob] h[0] = "01" [Bob] h[1] = "10" [Bob] h[2] = "001" [Bob] h[3] = "11" [Bob] h[4] = "000" The length of s is 42 and the cost is 82.
64 512 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
(Omitted)
編譯及測試教學請參考下列說明。
mysterious,請直接用命令列執行該檔案。#include "grader.cpp",並且以單一檔案的編譯執行方式測試,請注意這一行上傳時需要刪除,否則你會獲得一個 Compile Error。mysterious,請注意你需要確保 g++ 在系統的環境變數 PATH 中。YTP 2025 高中組程式挑戰營 p20
| No. | Testdata Range | Constraints | Score | 
|---|---|---|---|
| 1 | 0~1 | 範例測試資料。 | 0 | 
| 2 | 2 | $n = 3$、$(a_0, a_1, a_2) = (5, 2, 1)$。 | 1 | 
| 3 | 2~15 | $a_0 < 2^ 8$。 | 2 | 
| 4 | 16~32 | 無額外限制。 | 22 |