本題為 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 |