Anna 同 Bruno 都係考古學家,佢哋正喺伊朗調查遺跡。
佢哋嘅分工係:Anna 去遺跡發掘文物,而 Bruno 就喺大本營分析結果。
調查預計進行 $Q=1\,000$ 日。每日 Anna 都會用通訊裝置將結果傳畀 Bruno。每日嘅結果都用一個整數 $X$ 表示。
Anna 每日只可以用通訊裝置一次。裝置可以傳送一條長度為 $N=150$、由 $0$ 同 $1$ 組成嘅序列。
但係裝置壞咗。長度為 $N$ 嘅序列入面有幾個位置壞咗。對於壞咗嘅位置,無論實際設定咗咩值,傳出嘅值都一定係 $0$。Anna 傳送序列嗰陣可以睇到邊啲位置壞咗,但 Bruno 唔知道。壞咗嘅位置同數量每日都可以唔同。
佢哋嘅調查有可能因此延誤。因為你係喺伊朗舉行嘅國際程式設計比賽嘅選手候選人,Anna 同 Bruno 請你寫程式,傳送佢哋嘅調查結果。
任務
寫兩個程式,實現 Anna 同 Bruno 之間嘅通訊。
- 第一個程式獲得序列長度 $N$、要傳送嘅整數 $X$、壞咗嘅位置數目 $K$,以及壞咗嘅位置 $P$,然後設定 Anna 傳送嘅序列 $S$。
- 第二個程式獲得 Bruno 收到嘅序列 $A$,然後還原整數 $X$。
喺通訊裝置運作正常嘅位置,序列 $S$ 同序列 $A$ 嘅值一樣。喺壞咗嘅位置,無論序列 $S$ 嘅值係咩,序列 $A$ 嘅值都一定係 $0$。
實作細節
你要提交兩個用同一種程式語言寫成嘅檔案。
第一個檔案係 Anna.c 或 Anna.cpp。呢個檔案設定 Anna 要傳送嘅序列,並且實作以下函式。程式要包含 Annalib.h。
void Anna( int N, long long X, int K, int P[] )每個測試案例入面,呢個函式會被呼叫 $Q=1\,000$ 次。
- 參數
N係要傳送嘅序列長度。 - 參數
X係要傳送嘅整數。 - 參數
K係壞咗嘅位置數目。 - 參數
P[]係一條長度為 $K$ 嘅序列,描述壞咗嘅位置。
喺函式
Anna入面,必須呼叫以下函式。void Set( int pos, int bit )呢個函式設定通訊裝置要傳送嘅序列 $S$ 入面嘅一個位元。
- 參數
pos係要設定嘅位置。pos必須係 $0$ 至 $N-1$ 之間嘅整數,包括兩端。留意位置由 $0$ 開始計。如果呼叫時參數超出呢個範圍,程式會被判為Wrong Answer[1]。唔可以用同一個pos呼叫呢個函式多過一次;如果重複呼叫,程式會被判為Wrong Answer[2]。 - 參數
bit係設定喺序列第pos個位置嘅值。bit必須係 $0$ 或 $1$。如果用其他參數值呼叫,程式會被判為Wrong Answer[3]。
- 參數
喺函式
Anna入面,必須啱啱呼叫Set$N$ 次。當Anna結束嗰陣,如果Set嘅呼叫次數唔等於 $N$,程式會被判為Wrong Answer[4]。如果
Anna嘅函式呼叫被判為無效,你嘅程式就會終止。- 參數
第二個檔案係 Bruno.c 或 Bruno.cpp。呢個檔案還原表示調查結果嘅整數,並且實作以下函式。程式要包含 Brunolib.h。
long long Bruno( int N, int A[] )每個測試案例入面,呢個函式會被呼叫 $Q=1\,000$ 次。
- 參數
N係 Bruno 收到嘅序列長度。 - 參數
A係一條長度為 $N$ 嘅整數序列,亦即 Bruno 收到嘅序列。 - 函式
Bruno必須還原並回傳 $X$ 嘅值。
- 參數
評測流程
評測會按以下方式進行。如果程式被判為答案錯誤,就會立即終止。
- 設定 $\mathrm{cnt}=0$。
- 呼叫函式
Anna一次。 - 設 $S$ 為函式
Anna設定嘅序列。將 $S$ 入面 $P$ 所列位置嘅值設成 $0$,得到序列 $A$。以 $A$ 作為參數呼叫函式Bruno一次。 - 設定 $\mathrm{cnt}=\mathrm{cnt}+1$。如果 $\mathrm{cnt}<Q$,就去步驟 (2);如果 $\mathrm{cnt}=Q$,就去步驟 (5)。
- 為程式評分。
重要事項
- 執行時間同記憶體用量會計算評測流程嘅步驟 (1)、(2)、(3)、(4)。
- 喺步驟 (2) 呼叫
Anna或步驟 (3) 呼叫Bruno時,程式唔可以被判為答案錯誤,而且必須喺冇執行期錯誤嘅情況下執行。 - 程式可以實作其他內部函式,亦可以用全域變數。提交嘅程式會同評測程式一齊編譯成一個可執行檔。所有全域變數同內部函式都應該宣告為
static,避免同其他檔案衝突。評測時 Anna 同 Bruno 嘅程式會以兩個獨立行程執行,所以唔可以共用全域變數。 - 同一個行程入面,
Anna同Bruno都會各自被呼叫 $Q=1\,000$ 次。你應該適當初始化程式用到嘅變數。 - 程式唔應該用標準輸入同標準輸出,亦唔應該以任何方式同其他檔案通訊。
編譯同測試
你可以喺比賽網頁下載壓縮檔,入面有用嚟測試你嘅程式嘅範例評測程式,亦有你嘅程式嘅範例原始碼。
範例評測程式由一個原始碼檔案 grader.c 或 grader.cpp 組成。例如你嘅程式係 Anna.c 同 Bruno.c,或者 Anna.cpp 同 Bruno.cpp,就執行以下指令編譯。
C
gcc -std=c11 -O2 -o grader grader.c Anna.c Bruno.c -lm
C++
g++ -std=c++14 -O2 -o grader grader.cpp Anna.cpp Bruno.cpp
編譯成功後,就會產生可執行檔 grader。
留意實際評測程式同範例評測程式唔同。範例評測程式會以單一行程執行,從標準輸入讀取資料,再將結果寫去標準輸出。
範例評測程式嘅輸入格式
範例評測程式從標準輸入讀取以下資料。
- 第一行包含一個整數 $Q$。
- 然後提供 $Q$ 次查詢嘅資料。
每次查詢嘅資料由以下兩行組成。
- 第一行包含三個用空格分隔嘅整數 $N,X,K$。即係要傳送嘅序列長度係 $N$,Anna 要傳送嘅整數係 $X$,而壞咗嘅位置有 $K$ 個。
- 第二行包含 $K$ 個用空格分隔嘅整數 $P_0,P_1,\ldots,P_{K-1}$。即係對每個 $i$ ($0 \le i \le K-1$),序列第 $P_i$ 個位置壞咗。
範例評測程式嘅輸出格式
當程式成功結束,範例評測程式會將以下資料寫去標準輸出。(實際唔會寫出引號。)
- 如果程式被判為答案錯誤,範例評測程式會以
Wrong Answer [1]呢種格式寫出錯誤類型,然後你嘅程式就會終止。 - 如果每次呼叫
Anna都冇被判為答案錯誤,範例評測程式會寫出Accepted同 $L^*$ 嘅值。關於 $L^*$,請睇「評分」部分。
如果程式同時有幾種答案錯誤,範例評測程式只會報告其中一種。
資料範圍
所有輸入資料都符合以下條件。
- $Q=1000$。
- $N=150$。
- $0 \le X \le 1\,000\,000\,000\,000\,000\,000$。
- $1 \le K \le 40$。
- $0 \le P_i \le N-1$ ($0 \le i \le K-1$)。
- $P_i<P_{i+1}$ ($0 \le i \le K-2$)。
評分
設 $L^*$ 為呢題所有測試案例中,以下數值嘅最小值。
- 滿足以下條件嘅最大整數 $L \le 40$:對每次 $K \le L$ 嘅查詢,Bruno 都答出正確嘅 $X$ 值。
呢題嘅分數按以下方式計算:
- 如果 $L^*=0$,得 $0$ 分。
- 如果 $1 \le L^* \le 14$,得 $8$ 分。
- 如果 $15 \le L^* \le 37$,得 $(L^*-15)\times 2+41$ 分。
- 如果 $38 \le L^* \le 40$,得 $(L^*-38)\times 5+90$ 分。
範例
以下係評測程式嘅範例輸入同相應嘅函式呼叫。留意以下例子唔符合呢題嘅資料範圍,因為 $Q=2$、$N=3$。
輸入格式 1
2 3 14 1 2 3 9 2 0 1
範例呼叫
| 呼叫 | 回傳 | 呼叫 | 回傳 |
|---|---|---|---|
Anna(...) |
|||
Set(0,0) |
|||
| (無) | |||
Set(1,0) |
|||
| (無) | |||
Set(2,1) |
|||
| (無) | |||
| (無) | |||
Bruno(...) |
|||
14 |
|||
Anna(...) |
|||
Set(0,0) |
|||
| (無) | |||
Set(1,1) |
|||
| (無) | |||
Set(2,1) |
|||
| (無) | |||
Bruno(...) |
|||
9 |
以下係 Anna(...)、Bruno(...)、Anna(...)、Bruno(...) 嘅參數。
| 參數 | Anna(...) |
Bruno(...) |
Anna(...) |
Bruno(...) |
|---|---|---|---|---|
N |
3 |
3 |
3 |
3 |
X |
14 |
9 |
||
K |
1 |
2 |
||
P |
{2} |
{0, 1} |
||
A |
{0, 0, 0} |
{0, 0, 1} |