入選國際資訊奧林匹亞日本代表的 A 和 B,為了提升資訊處理技術,決定與資訊奧林匹亞日本委員會的 K 理事長進行「信使遊戲」。以下說明遊戲規則。
A 和 B 如圖所示,被隔離在各自的房間裡。A、B 和 K 理事長的房間都設有內線電話,但只有 K 理事長可以撥打電話。其他聯絡方式都被切斷,A 和 B 除非接到指示,否則不能離開房間。
A 的房間 — 長走廊 — K 理事長的房間 — 長走廊 — B 的房間
遊戲開始時,K 理事長透過電話告訴 A 一個正整數 $X$。遊戲的目標是在 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 叫到自己的房間。每次來到 K 理事長的房間時,A 或 B 都必須將棋子移至上、下、左、右其中一個相鄰格子,然後回到自己的房間。如果 B 來到 K 理事長的房間時已經知道 $X$ 的值,可以不移動棋子,改為向 K 理事長回答。回答正確的 $X$ 值即為答對,否則為答錯。
K 理事長叫 A 或 B 到房間的時機不規則,A 和 B 不知道兩人被叫去的順序。不過,K 理事長在遊戲開始時就已決定好順序,且保證不會連續叫同一個人超過 100 次。當兩人總共被叫到房間 $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 表示 A 抵達時棋子所在格子的整數對 $(I,J)$,滿足 $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 表示 B 抵達時棋子所在格子的整數對 $(I,J)$,滿足 $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 方,以兩個行程執行,因此雙方不能共用程式中的全域變數。
提交的程式不得以任何方式使用標準輸入、標準輸出或與其他檔案通訊。
編譯與執行方式
競賽網站可下載的壓縮檔包含供測試使用的範例評測程式,也包含必須提交檔案的範例。
範例評測程式由單一檔案 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被呼叫後,第一次呼叫GameA或GameB時,參數為 $I=1,J=1$。
子任務 3 [60 分]
- $T=3$。
互動範例
以下列出範例評測程式讀取的輸入範例,以及對應的函式呼叫範例。
輸入格式 1
2 6 1 1 ABBAABAAABBBBBABBAABBBABBBBAAAAABABAABAABBBBABAAAA
第二行後續部分省略。
函式呼叫範例
| A 方呼叫 | 回傳值 | 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 |
請注意,此範例不一定描述有意義的互動。