過咗幾百年,JOI 城已經變成一座廢墟。探險家 IOI-chan 而家正喺以前圖書館所在嘅地方探索。根據探索結果,已經知道以下事情:
- JOI 城嘅圖書館入面有一個橫向書架。書架有 $N$ 個排成一直線、用嚟放書嘅位置,由左至右編號做 $0$ 至 $N-1$。每個位置啱啱可以放一本書。
- 書架上有 $N$ 本書,編號做 $0$ 至 $N-1$。
- 書嘅排列方式,就係將全部 $N$ 本書放喺 $N$ 個位置上嘅方法。
- 書有一個正確排列,喺正確排列入面,位置 $i$ ($0 \le i \le N-1$) 放住編號 $B_i$ 嘅書。保證所有 $B_i$ 都互不相同。
書嘅排列經常會改變。我哋知道,呢間圖書館會重複以下操作,將所有書恢復到正確排列。
操作: 喺所有位置同正確排列唔同嘅書當中,設最左邊嗰本書係書 $x$。再設書 $y$ 係目前排列入面,放喺書 $x$ 喺正確排列應該所在位置嘅書。交換書 $x$ 同書 $y$ 嘅位置。
雖然 IOI-chan 搵到圖書館啲舊書,但佢唔知道正確排列係點。不過,佢搵到一部以前用嚟管理圖書館書架操作嘅舊機器。如果指定 $N$ 本書嘅排列,再向機器發出一次查詢,機器就會回答要用幾多次操作先可以將所有書恢復到正確排列。IOI-chan 想透過向機器查詢,得知書嘅正確排列。由於機器已經好舊,佢最多只可以向機器查詢 $5\,000$ 次。
請寫一個程式,根據書架嘅資訊,透過最多 $5\,000$ 次查詢,確定書嘅正確排列。
實作細節
你需要提交一個檔案。
呢個檔案係 library3.cpp,要實作以下函式。程式要用預處理指令 #include 引入 library3.h。
void solve(int N)
每個測試案例只會呼叫呢個函式一次。
- 參數
N係書嘅數量 $N$。
喺 library3.cpp 入面,你可以呼叫以下函式。
int query(const std::vector<int> a)
IOI-chan 透過呢個函式向機器查詢。
- 參數
a係長度為 $N$ 嘅陣列,表示查詢指定嘅 $N$ 本書嘅排列。即係喺指定排列入面,位置 $i$ 要放編號a[i]($0 \le i \le N-1$) 嘅書。 - 回傳值係由指定排列開始,將所有書恢復到正確排列所需嘅操作次數。
- 參數
a嘅長度必須係 $N$。如果唔符合呢個條件,程式會被判為答案錯誤 [1]。 - 參數
a嘅每個元素必須介乎 $0$ 至 $N-1$。如果唔符合呢個條件,程式會被判為答案錯誤 [2]。 - 參數
a嘅每個元素必須同其他所有元素都唔同。如果唔符合呢個條件,程式會被判為答案錯誤 [3]。 你唔可以呼叫
query超過 $5\,000$ 次。如果呼叫超過 $5\,000$ 次,程式會被判為答案錯誤 [4]。void answer(std::vector<int> b)
你嘅程式透過呼叫呢個函式,回答書嘅正確排列。
- 參數
b係長度為 $N$ 嘅陣列,表示答案指定嘅 $N$ 本書嘅排列。即係喺回答嘅排列入面,位置 $i$ 要放編號b[i]($0 \le i \le N-1$) 嘅書。 - 參數
b嘅長度必須係 $N$。如果唔符合呢個條件,程式會被判為答案錯誤 [5]。 - 參數
b嘅每個元素必須介乎 $0$ 至 $N-1$。如果唔符合呢個條件,程式會被判為答案錯誤 [6]。 - 參數
b嘅每個元素必須同其他所有元素都唔同。如果唔符合呢個條件,程式會被判為答案錯誤 [7]。 - 回答嘅排列必須係正確排列。如果唔符合呢個條件,程式會被判為答案錯誤 [8]。
answer必須啱啱呼叫一次。如果呼叫多過一次,程式會被判為答案錯誤 [9]。當solve結束時,如果仍然未呼叫過answer,程式會被判為答案錯誤 [10]。
重要注意事項
- 你嘅程式可以實作其他供內部使用嘅函式,亦可以使用全域變數。
- 你嘅程式唔可以使用標準輸入同標準輸出,亦唔可以用任何方法同其他檔案交換資料。不過,你可以向標準錯誤輸出除錯資訊。
編譯同試跑
你可以喺比賽網頁下載一個壓縮檔,入面包含用嚟測試你個程式嘅範例評測程式,亦包含你個程式嘅範例原始碼檔案。
範例評測程式係 grader.cpp。要測試你個程式,請將 grader.cpp、library3.cpp 同 library3.h 放喺同一個目錄,再執行以下指令編譯程式。你亦可以改為執行壓縮檔入面嘅 compile.sh。
g++ -std=gnu++20 -O2 -o grader grader.cpp library3.cpp
編譯成功後,會產生可執行檔 grader。
留意,實際評測程式同範例評測程式唔同。範例評測程式會以單一行程執行,從標準輸入讀取資料,並將結果寫到標準輸出。
範例評測程式嘅輸入格式
範例評測程式會從標準輸入讀取以下資料。
$$ \begin{array}{l} N \\ B_0\ B_1\ \cdots\ B_{N-1} \end{array} $$
$B_i$ ($0 \le i \le N-1$) 係正確排列入面,放喺位置 $i$ 嘅書嘅編號。
範例評測程式嘅輸出格式
範例評測程式會將以下資訊寫到標準輸出同標準錯誤輸出(引號只係用嚟表示清楚)。
- 如果你個程式被判為正確,佢會用「
Accepted: 3000」呢種格式報告query嘅呼叫次數。 - 如果你個程式被判為任何一種答案錯誤,範例評測程式會用「
Wrong Answer [3]」呢種格式寫出錯誤類型。
如果你個程式同時符合幾種答案錯誤嘅條件,範例評測程式只會報告其中一種。
數據範圍
所有輸入資料都符合以下條件。
- $2 \le N \le 500$。
- $0 \le B_i \le N-1$ ($0 \le i \le N-1$)。
- $B_i \ne B_j$ ($0 \le i<j \le N-1$)。
- 所有畀定嘅值都係整數。
子任務
- (2 分)$N \le 6$。
- (19 分)$N \le 100$。
- (79 分)冇額外限制。
樣例
以下係範例評測程式嘅一份樣例輸入,以及對應嘅函式呼叫。
輸入格式 1
4
2 0 3 1
說明
樣例函式呼叫:
| 呼叫 | 呼叫 | 回傳值 |
|---|---|---|
solve(4) |
||
query([0, 1, 2, 3]) |
$3$ | |
query([1, 3, 0, 2]) |
$2$ | |
query([3, 0, 1, 2]) |
$2$ | |
query([2, 0, 3, 1]) |
$0$ | |
answer([2, 0, 3, 1]) |
例如,呼叫 query([0, 1, 2, 3]) 指定嘅排列,係將書 $0,1,2,3$ 分別放喺位置 $0,1,2,3$。操作會按以下方式重複。
- 交換書 $0$ 同書 $1$ 嘅位置。位置 $0,1,2,3$ 分別放住書 $1,0,2,3$。
- 交換書 $1$ 同書 $3$ 嘅位置。位置 $0,1,2,3$ 分別放住書 $3,0,2,1$。
- 交換書 $3$ 同書 $2$ 嘅位置。位置 $0,1,2,3$ 分別放住書 $2,0,3,1$。
因為將所有書恢復到正確排列需要 $3$ 次操作,所以回傳值係 $3$。
呢份樣例輸入符合所有子任務嘅限制。