獲選為國際資訊奧林匹克日本代表嘅 A 同 B,為咗提升資訊處理技術,決定同日本資訊奧林匹克委員會嘅 K 理事長玩「信使遊戲」。以下介紹遊戲規則。
A 同 B 各自被隔離喺房間入面,如圖所示。A、B 同 K 理事長嘅房間都裝有內線電話,但只有 K 理事長可以打出電話。其他聯絡方法全部被切斷,而且 A 同 B 冇收到指示就唔可以離開房間。
A 嘅房間 長走廊 K 理事長嘅房間 長走廊 B 嘅房間
遊戲開始嗰陣,K 理事長會打電話將一個正整數 $X$ 話畀 A 知。遊戲目標係 A 同 B 唔直接聯絡嘅情況下,由 A 將 $X$ 嘅值正確傳畀 B。
K 理事長嘅房間有一個 $4\times4$ 方格棋盤。用 $(i,j)$ 表示第 $i$ 行第 $j$ 列嘅格($1\le i\le4$,$1\le j\le4$)。$(1,1)$ 係左上角,$(1,4)$ 係右上角,$(4,1)$ 係左下角,$(4,4)$ 係右下角。遊戲開始嗰陣,一粒棋子會擺喺其中一格。之後 K 理事長唔會改變棋子所在嘅格。
之後,K 理事長會不斷打電話叫 A 或 B 去佢嘅房間。A 或 B 每次嚟到 K 理事長嘅房間,都必須將棋子移去上、下、左、右其中一個相鄰格。移完棋子之後,就返自己嘅房間。如果 B 嚟到 K 理事長嘅房間嗰陣已經知道 $X$ 嘅值,就可以唔移棋子,改為將答案話畀 K 理事長知。答出正確嘅 $X$ 值就算答對,否則就算答錯。
K 理事長叫 A 或 B 嚟房間嘅時間冇規律,A 同 B 唔知道佢用咩次序叫兩個人過嚟。不過,K 理事長喺遊戲開始嗰陣已經決定好叫人嘅次序,並保證唔會連續叫同一個人超過 $100$ 次。當 K 理事長總共叫咗 A 同 B 嚟房間 $10\,000$ 次,而該次到訪嘅人返到自己房間嗰陣,如果 B 仲未答出 $X$ 嘅值,遊戲就會以答錯結束。
任務
請實作 A 同 B 嘅策略,寫一個可以喺上述「信使遊戲」答對嘅程式。
實作細節
你必須提交兩個用同一種程式語言編寫嘅檔案。
第一個檔案叫 playerA.c 或 playerA.cpp,用嚟實作 A 嘅策略,必須實作以下函式。
void InitA(int T, int X)
呢個函式只會喺最初呼叫一次。參數 T 係子任務編號 $T$。參數 X 係 A 要傳畀 B 嘅正整數 $X$。
int GameA(int I, int J)
每當 A 嚟到 K 理事長嘅房間,就會呼叫呢個函式。參數 I、J 係整數對 $(I,J)$,表示 A 嚟到嗰陣棋子所在嘅格,滿足 $1\le I\le4$ 同 $1\le J\le4$。
呢個函式必須傳回整數 $-1,-2,-3,-4$ 其中一個。如果傳回其他值,就會判為答錯 [1],並終止程式執行。各個值表示 A 採取以下行動。
- $-1$:將棋子移去上面嘅格 $(I-1,J)$。
- $-2$:將棋子移去下面嘅格 $(I+1,J)$。
- $-3$:將棋子移去左面嘅格 $(I,J-1)$。
- $-4$:將棋子移去右面嘅格 $(I,J+1)$。
如果指定嘅移動會令棋子走出棋盤,就會判為答錯 [2],並終止程式執行。
第二個檔案叫 playerB.c 或 playerB.cpp,用嚟實作 B 嘅策略,必須實作以下函式。
void InitB(int T)
呢個函式只會喺最初呼叫一次。參數 T 係子任務編號 $T$。
int GameB(int I, int J)
每當 B 嚟到 K 理事長嘅房間,就會呼叫呢個函式。參數 I、J 係整數對 $(I,J)$,表示 B 嚟到嗰陣棋子所在嘅格,滿足 $1\le I\le4$ 同 $1\le J\le4$。
呢個函式必須傳回整數 $-1,-2,-3,-4$ 其中一個,或者一個正整數 $Y$。如果傳回其他值,就會判為答錯 [3],並終止程式執行。各個值表示 B 採取以下行動。
- $-1$:將棋子移去上面嘅格 $(I-1,J)$。
- $-2$:將棋子移去下面嘅格 $(I+1,J)$。
- $-3$:將棋子移去左面嘅格 $(I,J-1)$。
- $-4$:將棋子移去右面嘅格 $(I,J+1)$。
如果指定嘅移動會令棋子走出棋盤,就會判為答錯 [4],並終止程式執行。
- 正整數 $Y$:向 K 理事長回答「$X$ 嘅值係 $Y$」。如果 $X=Y$ 就判為答對,否則判為答錯 [5],並終止程式執行。
GameA 同 GameB 之中,唔會有其中一個被連續呼叫超過 $100$ 次。如果兩個函式總共被呼叫咗 $10\,000$ 次,而 GameB 仲未傳回過正整數,就會判為答錯 [6],並終止程式執行。
你可以自由實作其他內部使用嘅函式,或者宣告全域變數。不過,提交嘅兩個程式會同評測程式一齊連結成一個可執行檔,所以每個檔案入面所有全域變數同內部函式都必須用 static 宣告,以免同其他檔案互相干擾。評測時,呢個程式會分別以 A 方同 B 方兩個程序執行,所以 A 同 B 唔可以共用程式入面嘅全域變數。
你提交嘅程式唔可以用任何方法同標準輸入、標準輸出或者其他檔案進行資料往來。
編譯同執行方法
可以喺比賽網站下載嘅壓縮檔入面,有一個用嚟測試你嘅程式嘅範例評測程式。壓縮檔亦包含需要提交嘅檔案範例。
範例評測程式由一個檔案組成,即 grader.c 或 grader.cpp。要測試你寫嘅程式,可以執行以下指令。
- C:
gcc -O2 -lm grader.c playerA.c playerB.c -o grader
- C++:
g++ -O2 -lm grader.cpp playerA.cpp playerB.cpp -o grader
編譯成功後,就會產生一個叫 grader 嘅可執行檔。
請留意,實際評測程式同範例評測程式唔同。範例評測程式只會以一個程序啟動,從標準輸入讀取資料,並將結果寫去標準輸出。
輸入格式
範例評測程式會從標準輸入讀取以下資料。
- 第一行有以空格分隔嘅整數 $T,X,I_0,J_0$,表示子任務編號係 $T$,A 要傳畀 B 嘅整數係 $X$,遊戲開始嗰陣棋子喺 $(I_0,J_0)$。
- 第二行有一條只由
A同B組成、長度恰好係 $10\,000$ 嘅字串。如果第 $k$ 個字元($1\le k\le10\,000$)係A或B,就分別表示喺InitA同InitB被呼叫之後,第 $k$ 次呼叫嘅函式係GameA或GameB。
輸出格式
如果程式正常結束執行,範例評測程式會喺標準輸出用一行輸出以下資料。
- 答對時會輸出
Accepted(實際唔會輸出引號,以下亦一樣)。 - 答錯時,會按「實作細節」所列嘅編號輸出答錯類型,例如
Wrong Answer [1]。另外,對於答錯 [5],亦會輸出正確嘅 $X$ 值同GameB傳回嘅正整數 $Y$ 值,例如Wrong Answer [5] : X = 2, Y = 3。
資料範圍
所有輸入資料都滿足以下條件。
- $1\le X\le1\,000\,000\,000$。
子任務
子任務 1 [20 分]
- 滿足 $T=1$。
- 最先被叫去 K 理事長房間嘅係 A,之後 A 同 B 輪流被叫去。即係
InitA同InitB被呼叫之後,會按GameA, GameB, GameA, GameB, ...嘅次序呼叫函式。
子任務 2 [20 分]
- 滿足 $T=2$。
- 遊戲開始嗰陣,棋子位置係 $(I_0,J_0)=(1,1)$。即係
InitA同InitB被呼叫之後,首先會用 $I=1,J=1$ 作為參數呼叫GameA或GameB。
子任務 3 [60 分]
- 滿足 $T=3$。
範例
以下係範例評測程式讀取嘅輸入例子,同相應嘅函式呼叫例子。
輸入格式 1
2 6 1 1 ABBAABAAABBBBBABBAABBBABBBBAAAAABABAABAABBBBABAAAA
(原文省略咗字串餘下部分。)
| A 方:呼叫 | A 方:傳回值 | B 方:呼叫 | B 方:傳回值 |
|---|---|---|---|
InitA(2, 6) |
無 | ||
InitB(2) |
無 | ||
GameA(1, 1) |
$-2$ | ||
GameB(2, 1) |
$-4$ | ||
GameB(2, 2) |
$-2$ | ||
GameA(3, 2) |
$-3$ | ||
GameA(3, 1) |
$-1$ | ||
GameB(2, 1) |
$6$ |
說明
請留意,呢個例子未必描述咗有意義嘅資料往來。