你有冇聽過 Just Ordinary Inventions 公司?呢間公司嘅業務就係做「平平無奇嘅發明」。
JOI 君正玩緊 Just Ordinary Inventions 公司開發嘅最新遊戲。
呢個遊戲要探索一個由若干房間同道路組成嘅地牢。每條道路連接地牢入面兩個唔同嘅房間,可以雙向通行。任意兩個唔同房間之間最多只有一條道路,亦冇道路嘅兩端係同一個房間。已知地牢入面任意兩個房間都可以經過若干條道路互相到達。各個房間非常相似,道路數量相同嘅房間,單憑房間嘅外觀完全分辨唔到。
為咗幫助玩家過關,每個房間都設有一個標記同一個底座。以標記為基準,可以將房間連住嘅道路數做第 $1$ 條、第 $2$ 條、……。遊戲期間地牢嘅結構唔會改變,所以由同一個房間沿同一編號嘅道路移動,總會到達同一個房間。底座上擺住一粒玩家可以改色嘅寶石。寶石嘅顏色係顏色 $1$、顏色 $2$、……、顏色 $X$ 其中一種,遊戲開始時每個房間嘅寶石都係顏色 $1$。除非玩家操作,否則寶石唔會自行改色。
JOI 君發現,只要知道地牢嘅結構,即係各個房間點樣由道路連接,就可以輕鬆過關。不過,佢試過好多方法,都未能確定地牢嘅結構。所以你決定代替 JOI 君,寫一個程式去確定地牢嘅結構。
任務
請寫一個程式,探索地牢並確定佢嘅結構。不過,JOI 君唔希望地牢結構被完全公開,所以程式唔應該直接回答地牢嘅結構,而係要對每個 $1$ 至 $R$ 嘅整數 $i$,回答「最少恰好要用 $i$ 條道路先可以互相到達嘅房間對有幾多個」(交換兩個房間嘅次序視為同一對)。
為咗探索地牢,你可以用提供嘅函式庫進行以下操作。
- 得知而家所在房間連住幾多條道路。
- 得知而家所在房間底座上嘅寶石顏色。
- 將而家所在房間底座上嘅寶石改成指定顏色(亦可以指定原本嘅顏色),然後揀一條連住呢個房間嘅道路,沿住佢移動到另一個房間。
- 得知最後用過嘅道路,係而家所在房間連住嘅第幾條道路。
實作細節
你必須寫一個程式,實作向 JOI 君回答嘅方法。程式要引入 dungeon2.h。
程式必須實作以下函式。
void Inspect(int R)
呢個函式喺最開始只會被呼叫一次。
- 參數
R表示:對每個 $1$ 至 $R$ 嘅整數 $i$,你必須回答「最少恰好要用 $i$ 條道路先可以互相到達嘅房間對有幾多個」(交換房間次序視為同一對)。
另外,你必須呼叫以下函式嚟回答問題。
void Answer(int D, int A)
- 參數
D、A表示呢次呼叫回答:「最少恰好要用 $D$ 條道路先可以互相到達嘅房間對有 $A$ 個」。
呼叫 Answer 必須滿足以下條件。
- $D$ 必須係 $1$ 至 $R$ 嘅整數,否則會判為答案錯誤 [1]。
- 唔可以用同一個參數
D呼叫Answer兩次或以上,否則會判為答案錯誤 [2]。 - 必須恰好呼叫
Answer$R$ 次,否則會判為答案錯誤 [3]。 - $A$ 必須等於最少恰好要用 $D$ 條道路先可以互相到達嘅房間對數,否則會判為答案錯誤 [4]。
如果 Answer 嘅呼叫被判為答案錯誤,之後嘅程式未必會繼續執行。
除此之外,你亦可以喺程式入面呼叫以下函式。
void Move(int I, int C)
- 參數
I係玩家揀嚟移動嘅道路編號。呼叫之後,玩家立即沿而家所在房間嘅第 $I$ 條道路移動到另一個房間。 - 參數
C表示喺移動之前,將而家所在房間底座上嘅寶石改成顏色 $C$。
呼叫 Move 必須滿足以下條件。
- 設而家所在房間連住 $K$ 條道路,參數
I必須係 $1$ 至 $K$ 嘅整數,否則會判為答案錯誤 [5]。 - 設寶石一共有 $X$ 種顏色,參數
C必須係 $1$ 至 $X$ 嘅整數。$X$ 嘅值由各個子任務決定。唔滿足條件會判為答案錯誤 [6]。 - 唔可以呼叫
Move超過 $1\,500\,000$ 次,否則會判為答案錯誤 [7]。
int NumberOfRoads()
- 呢個函式傳回玩家而家所在房間連住嘅道路數量。
int LastRoad()
- 呢個函式傳回玩家最後用過嘅道路,係而家所在房間連住嘅第幾條道路。不過,如果喺未呼叫過
Move之前呼叫呢個函式,就會傳回 $-1$。
int Color()
- 呢個函式傳回玩家而家所在房間底座上嘅寶石顏色。
呼叫 Inspect 之後,就會判定答案。
你可以自由實作其他函式作內部用途,亦可以宣告全域變數。不過,你提交嘅程式唔可以透過任何方法同標準輸入、標準輸出,或者其他檔案交換資料。
編譯同執行方法
比賽網站提供嘅壓縮檔入面,有用嚟測試你程式嘅評測程式範例,亦有你需要提交嘅檔案範例。
評測程式範例由一個檔案組成,檔名係 grader.c 或 grader.cpp。要測試你嘅程式,請執行以下命令。
- 使用 C 時:
gcc -std=c11 -O2 -o grader grader.c dungeon2.c -lm
- 使用 C++ 時:
g++ -std=c++11 -O2 -o grader grader.cpp dungeon2.cpp
編譯成功後,會產生名為 grader 嘅可執行檔。
請留意,實際評測程式同評測程式範例並唔相同。評測程式範例會以單一行程啟動,從標準輸入讀取資料,並向標準輸出寫出結果。
評測程式範例嘅輸入格式
評測程式範例會從標準輸入讀入以下資料。
- 第一行包含以空格分隔嘅整數 $N,X,R$,表示地牢有房間 $1$、房間 $2$、……、房間 $N$,合共 $N$ 個房間;寶石有 $X$ 種顏色;程式需要回答 $R$ 個數值。
- 接落嚟 $2N$ 行中,第 $2i-1$ 行($1 \le i \le N$)包含一個整數 $D_i$,表示房間 $i$ 連住 $D_i$ 條道路。第 $2i$ 行($1 \le i \le N$)包含 $D_i$ 個以空格分隔嘅整數 $T_{i1},T_{i2},\ldots,T_{iD_i}$,表示由房間 $i$ 沿第 $j$ 條道路($1 \le j \le D_i$)移動,會到達房間 $T_{ij}$。
- 接落嚟 $R$ 行中,第 $j$ 行($1 \le j \le R$)包含一個整數 $A_j$,表示最少恰好要用 $j$ 條道路先可以互相到達嘅房間對有 $A_j$ 個。即係對每個 $j$($1 \le j \le R$),用
D為 $j$、A為 $A_j$ 呼叫Answer時,評測程式範例會判為正確,其他情況就判為答案錯誤。
評測程式範例會將玩家嘅初始位置設為房間 $1$,再呼叫你實作嘅函式。
評測程式範例嘅輸出格式
如果程式正常結束,評測程式範例會向標準輸出寫出以下一行資訊(實際唔會輸出引號)。
- 如果答案正確,會以
Accepted : #move = 8呢種形式輸出呼叫Move嘅次數。 - 如果答案錯誤,會以
Wrong Answer [1]呢種形式輸出答案錯誤嘅類型。
數據範圍
所有輸入資料都滿足以下條件。$N,D_i,T_{ij}$ 嘅意思,請參考「評測程式範例嘅輸入格式」。
- $2 \le N \le 200$。
- $3 \le X \le 100$。
- $1 \le R \le 200$。
- $1 \le D_i \le N-1$($1 \le i \le N$)。
- $1 \le T_{ij} \le N$,而且 $T_{ij} \ne i$($1 \le i \le N$,$1 \le j \le D_i$)。
- $T_{i1},T_{i2},\ldots,T_{iD_i}$($1 \le i \le N$)彼此唔同。
- 對每個 $i,j$($1 \le i \le N$,$1 \le j \le D_i$),都存在 $k$($1 \le k \le D_{T_{ij}}$)令 $T_{T_{ij}k}=i$。
- 任意兩個房間都可以經過若干條道路互相到達。
子任務
以下用 $N$ 表示輸入地牢嘅房間數,用 $M$ 表示道路數。
子任務 1[17 分]
滿足以下條件。
- $N \le 50$。
- $M \le 100$。
- $X=100$。
子任務 2[27 分]
滿足以下條件。
- $N \le 50$。
- $M \le 100$。
- $X=3$。
子任務 3[56 分]
- $X=3$。
呢個子任務按以下方式計分。
設以下數值喺呢個子任務所有測試案例中嘅最大值為 $L$。
- 設呼叫
Move嘅次數為 $C$,該數值就係 $\frac{C}{M}$。
- 設呼叫
呢個子任務嘅得分為:
- 當 $L \le 14$ 時,$56$ 分。
- 當 $14 < L \le 32$ 時,$\lfloor 70-L\rfloor$ 分。
- 當 $32 < L \le 64$ 時,$\left\lfloor 54-\frac{L}{2}\right\rfloor$ 分。
- 當 $64 < L$ 時,$0$ 分。
呢度 $\lfloor x\rfloor$ 表示唔大於 $x$ 嘅最大整數。
喺評測系統上,如果程式正常結束而且答案正確,詳細資料欄會顯示 Accepted。不過請留意,評測子任務 3 時,如果某個測試案例嘅上述 $C,M$ 滿足 $64 < \frac{C}{M}$,結果欄就會顯示答案錯誤。
互動範例
以下係評測程式範例讀入嘅輸入範例,同對應嘅函式呼叫範例。
輸入格式 1
4 3 3 1 2 3 1 3 4 2 2 4 2 2 3 4 2 0
函式呼叫範例
| 呼叫 | 傳回值 |
|---|---|
Inspect(3) |
|
NumberOfRoads() |
1 |
LastRoad() |
-1 |
Move(1,2) |
|
Color() |
1 |
LastRoad() |
1 |
NumberOfRoads() |
3 |
Move(1,3) |
|
Color() |
2 |
Answer(1,4) |
|
Answer(2,2) |
|
Answer(3,0) |
請留意,呢個範例入面嘅函式呼叫未必全部都有實際意義。