來自軟體工程系的小 W 正在工程製圖的考場上,而他只帶了一把被歲月磨光了刻度的直尺和一副圓規。百般無奈的他只能求助於有著驚人幾何作圖能力的你。現在請你使用不帶刻度的直尺和圓規,幫助小 W 又快又精確地完成製圖。
我們來簡化一下這個問題。假設小 W 已經得到了座標系及單位長度,他需要你用尺規作出長度 $L_0$,即得到點 $(L_0,0)$。
你可以使用以下三種操作:
- $line(A,B)$:作出通過點 $A$ 與點 $B$ 的直線;
- $circle(O,A,B)$:以 $AB$ 間的距離為半徑,以點 $O$ 為圓心畫圓;
- $intersect(i,j)$:標記第 $i$ 個圖形與第 $j$ 個圖形的所有交點,有多個就標記多個。
初始時小 W 為你提供了原點 $O(0,0)$,編號為 $0$。單位長度由 $1$ 號點 $(1,0)$ 給出。此外提供 $x$ 軸($0$ 號圖形)和 $y$ 軸($1$ 號圖形)。
所有在操作中得到的新點和圖形都會接著編號。
設目前編號為 $n$,則 $intersect$ 操作產生的點會被標記為 $n+1$。
若兩圖形沒有交點,則不會產生新點。
若有兩個交點,則 $x$ 值較小($x$ 值相同時 $y$ 較小)的會被標記為 $n+1$,另一個為 $n+2$。
請你得到點 $(L_0,0)$,並指明其編號。你不需要得到精確值,但你與精確值的差距以及使用的操作數都與得分相關。
輸入格式
本題為提交答案型試題,所有輸入資料 draw1.in~draw10.in 已在試題目錄下。
每份輸入資料 $x_0$ 都是一個 python 計算運算式。其中 ** 表示冪次運算,例如 3 ** 2 表示 $3^2$,2 ** 0.5 表示 $\sqrt2$。
為了提供較高精度,運算式中的數轉為 decimal 型別,即高精度小數。其中 Decimal(2) 就表示 $2$。
輸入保證數與符號、符號與符號之間會以一個空格隔開。
python 程式碼的輸出為要求構造的數。
注意,直接用 python 計算得到的結果是近似值,而實際要求的是精確值,即與選手所得結果比較的值是精確值。
另外,我們還提供了一個檔案 draw.pdf,以便於閱讀的方式給出每組資料的運算式。
輸出格式
針對給定的 10 個輸入檔案 draw1.in~draw10.in,你需要分別提交輸出檔案 draw1.out~draw10.out。
輸出檔案的第一行為一個整數 $n$,表示操作數。接下來 $n$ 行,每行一條操作,三種操作對應的格式為:
line: L A B circle: C O A B intersect: I i j
參數意義如題目敘述所述。
輸出檔案的最後一行為一個整數,表示最終得到的點的編號。
範例
輸入格式 1
Decimal( 2 ) ** ( Decimal( 1 ) / Decimal( 2 ) )
輸出格式 1
5 C 0 0 1 I 1 2 C 0 1 3 L 1 3 I 0 3 5
說明
範例中的五個操作意義如下:
- 以 $O$ 點為圓心、單位長度為半徑畫圓,該圓為 $2$ 號圖形;
- 取 $2$ 號圖形(圓)與 $y$ 軸的交點,交點編號為 $2(0,-1)$、$3(0,1)$;
- 以 $O$ 點為圓心,以 $1$ 號點與 $3$ 號點的距離為半徑畫圓,該圓為 $3$ 號圖形;
- 連結點 $(1,0)$、$(0,1)$,產生的直線為 $4$ 號圖形。
- 取 $3$ 號圖形(圓)與 $x$ 軸的交點,交點編號為 $4(-\sqrt2,0)$、$5(\sqrt2,0)$。
因此 $5$ 號點就是最終需要得到的點。
子任務
針對給定的 10 個輸入檔案 draw1.in~draw10.in,我們分別提供評分參數檔案 draw1.ans~draw10.ans。
評分參數檔案共十行,每行兩個數 $c_i,x_i$,表示若最終得到的點 $(x,0)$ 的橫座標 $x$ 與 $L_0$ 的絕對值之差不超過 $10^{-x_i}$,且使用的操作數 $n\le c_i$,則可得 $i$ 分。
評測會取所有滿足條件的最高分,若不滿足任何條件則得 0 分。
如何測試你的輸出
我們提供 checker 這個工具來測試你的輸出檔案是否可接受。使用方法是先進入終端機,在終端機中執行以下指令,進入本題的資料夾:
cd draw
然後執行:
./checker <case_no>
其中 case_no 是測試資料的編號。例如:
./checker 3
會測試 draw3.out 是否可接受。
呼叫這個程式後,checker 會根據你的輸出檔案給出測試結果,包括:
- 非法結束:未知錯誤。
Invalid parameters for checker.:傳給 checker 的參數不合法。Input/Output file does not exist.:輸入/輸出檔案不存在。Output invalid:輸出檔案有誤,此時可能包含具體錯誤資訊。Correct! Your answer is n. Your score is s.:輸出可接受,使用的操作數為 $n$,此測試點的得分為 $s$。
更多功能
checker 還可以檢查任意輸入輸出檔案的測試結果,方法是在終端機中執行:
cd draw ./checker <input_file> <output_file> <ans_file>
其中 input_file、output_file 和 ans_file 分別是輸入、輸出及評分參考檔案的名稱。
例如:
./checker draw3.in draw3.out draw3.ans
會測試 draw3.out 是否可接受。
使用 -w 可以輸出產生的每個點的座標。輸出中每行的格式為:
id x y
分別表示點的編號、$x$ 座標、$y$ 座標。具體用法是:
./checker -w <input_file> <output_file> <ans_file>
或者:
./checker -w <case_no>
例如:
./checker -w draw3.in draw3.out draw3.ans
使用 -i 可以同時輸出選手的輸出,方便除錯。具體用法是:
./checker -i <input_file> <output_file> <ans_file>
或者:
./checker -i <case_no>
例如:
./checker -i draw3.in draw3.out draw3.ans
使用 -e prec 可以指定 checker 運算時的精度(有效位數)。不使用此選項時,預設 prec 為 $200$。具體用法是:
./checker -e <prec> <input_file> <output_file> <ans_file>
或者:
./checker -e <prec> <case_no>
例如:
./checker -e 50 draw3.in draw3.out draw3.ans
-e prec、-w 與 -i 選項可同時加入,順序不限,例如:
./checker -w -i -e 50 draw3.in draw3.out draw3.ans
說明
我們可以利用 python 得到運算式的近似值。具體來說,在終端機中執行 python 後,輸入:
from math import * from decimal import * getcontext().prec = 100
然後將輸入檔案中的運算式(python 程式碼)複製到該終端機視窗並按 Enter,即可得到運算式的近似值(上述程式碼中的 100 可替換為你想要的精度)。
特別說明
如果選手使用自行產生的輸入檔案除錯,可能因規模過大造成 checker 出錯。若發生這類情況,請嘗試較小規模的資料。
請妥善保存輸入檔案 draw.in、你的輸出檔案 draw.out 和評分參數檔案 draw*.ans,及時備份,以免誤刪。