算對了公式,卻因為複製貼上舊答案輸掉四次——STARPWN 2026「Time to Intercept」解題筆記
這題跟前面幾篇無人機蜂群系列不一樣,是一個純軌道力學計算題,用
nc連上一個互動式的 shell,題目會即時報數字給你,要在限定次數內把兩個答案送回去。內容本身其實是一道扎實的物理計算題,但真正讓我印象深刻的,是我後來重連一個新的實例時,蠢到把上一輪的答案複製貼上,就一直連續錯了四次
題目在講什麼
An unknown aggressor satellite has been detected in a higher orbit and is threatening critical space infrastructure. Your mission: calculate a Hohmann transfer to intercept it.
翻成白話:偵測到一顆敵方衛星在比我方更高的軌道上,正在威脅重要太空基礎設施。任務是算出一個 Hohmann transfer(霍曼轉移軌道),攔截它。連上題目給的 shell 之後,畫面會告訴你三件事:自己所在圓形軌道的半徑跟速度、目標衛星所在圓形軌道的半徑跟速度、還有你們兩個目前的相位角(phase angle,簡單說就是兩顆衛星目前繞地球的角度差,題目要求要回傳兩個數字:
1 | delta_v_burn wait_time |
delta_v_burn 是要花多少速度變化量(Δv,單位 m/s)去點火進入轉移軌道;wait_time 是要先等多少秒才點火,才能讓自己跟目標衛星剛好在同一時間抵達會合點。誤差容許範圍是 Δv ±10 m/s、等待時間 ±60 秒,每條連線只有 5 次提交機會,答錯或連線斷了就要重連拿一組全新的隨機題目
背景知識:什麼是 Hohmann transfer
Hohmann transfer 是航太工程裡最基本、也最省油的軌道轉移方式:如果你在一個低軌道,想換到另一個同心的高軌道,不需要一路加速上去,只要在正確的時間點做兩次點火。
第一次把自己送上一個橢圓形的「轉移軌道」,這個橢圓一端貼著原本的低軌道,另一端剛好貼著目標的高軌道,第二次點火則是在到達高軌道那一端時,把自己「拉直」成新的圓形軌道。
有興趣可以看這個影片:https://youtu.be/KdHI5Fn9Fu8
這題只計分第一次點火(進入轉移軌道那一下),所以問題簡化成:算出第一次點火要花多少 Δv,以及要挑哪個時間點火,才能讓自己跟目標衛星在轉移軌道的另一端準時碰頭。
這其實是個很標準的軌道力學問題,關鍵在兩塊:點火要花多少速度變化量,跟該等多久再點火。
算 Δv:標準 vis-viva 方程式
轉移橢圓的半長軸(transfer ellipse semi-major axis)就是自己軌道半徑跟目標軌道半徑的平均:
1 | a_t = (r1 + r2) / 2 |
用 vis-viva 方程式(描述橢圓軌道上任一點速度跟半徑關係的公式)算出轉移軌道在起點(也就是自己目前所在半徑 r1)的速度:
1 | v_p = sqrt(mu * (2/r1 - 1/a_t)) |
這裡有個小訣竅:mu(重力參數,等於地球質量乘上重力常數)不要用課本上的標準地球值 398600.4418 km³/s² 去代,而是直接從題目自己印出來的圓軌道速度反推:
1 | mu = v1**2 * r1 # 自洽的重力參數,直接從自己的圓軌道速度反推,不假設任何課本常數 |
因為在圓形軌道上,重力提供的向心力剛好等於 v² / r = mu / r²,兩邊消一消就是 mu = v² * r。這樣算出來的 Δv,跟伺服器內部算出來的正確答案幾乎完全吻合(誤差在 0.001 m/s 等級),完全不用擔心題目背後用的地球半徑或 GM 常數跟課本定義是否一致。
算等待時間:真正卡住的地方
轉移軌道走完一半橢圓(從起點飛到會合點)需要的時間:
1 | t_transfer = π * sqrt(a_t³ / mu) |
古典的 Hohmann 交會相位理論是這樣:假設自己在內側、速度較快的軌道(角速度 n1 = v1/r1),目標在外側、速度較慢的軌道(角速度 n2 = v2/r2),要讓兩者剛好在轉移橢圓的另一端(180 度外)相遇,點火那一刻目標必須領先自己一個特定角度:
1 | φ_required = π − n2 · t_transfer |
(直覺理解:轉移過程中,自己會掃過整整 180 度,而目標只會前進 n2 · t_transfer 這麼多角度,所以目標得先領先這麼多,才能讓兩者同時抵達。)
問題來了:拿到題目印出來的目前相位角 φ0 之後,等待時間該怎麼從 φ0 跟 φ_required 的差推出來?照課本直覺寫的公式:
1 | t_wait = [(φ0 − φ_required) mod 2π] / (n1 − n2) |
但這個公式是錯的 第一次照這個公式送出 Δv=160.73, wait_time=16997.80,結果 Δv 被接受,但 wait time 被判定錯誤(Wait time error too large
這個部分被拒絕的訊息其實是個很精準的診斷,因為代表轉移軌道本身的物理算式(a_t、v_p、t_transfer)完全沒問題,唯一有問題的是相位角的方向定義
既然只有 wait time 被打回票,問題就一定出在題目給的 phase angle 到底怎麼對應到公式裡的 φ0,而不是轉移軌道力學本身,如果把減法的順序反過來,也就是改成 「φ0 還要往另一個方向繞多少角度才能到達 φ_required」 就得到跟伺服器真正吻合的公式:
1 | t_wait = ((phi_required - phase0) % (2*math.pi)) / (n1 - n2) |
完整驗證:
1 | import math |
送出 121.935 26900.962:
1 | Submitted delta-v: 121.935 m/s Required: 121.934 m/s Error: 0.001 m/s |
以上是最初那版Time to Intercept的完整解法。
後來題目重開了一個 V2 版本,同樣的服務、同樣的評分方式,只是換了個 port,照理說公式直接照搬就能用,實際上也的確如此,但是真正有趣的是接下來發生的事
V2:同一套公式,卻因為手滑連錯四次
V2 的題目描述、格式、誤差範圍完全跟 V1 一樣,唯一差別是題目重新給了一組全新的隨機參數。連上新的實例,畫面印出:
1 | YOUR SATELLITE: DEFENDER-1 |
問題是,我在連上這個全新instance之前,才剛結束另一條連線(那條連線的參數是 r1=6850.870 km、r2=7534.987 km、phase=199.425°,算出來的 Δv 是 179.259)連上新的這條之後,前四次提交我只顧著調整 wait time,Δv 卻一直沿用上一條連線算出來的 179.26:
1 | 第 1 次:179.26 22068.88 -> 兩個都錯 |
每次回應都是 Delta-v error too large
這其實已經是伺服器在明示:問題出在 Δv 本身要重算,而不是 wait time 猜得不夠準,每條連線的題目參數是固定的(同一條連線的 5 次機會共用同一組 r1/r2/v1/v2/phase),但不同連線之間的參數完全不共用。 把上一條連線算對的 Δv 直接複製貼到新連線,數字看起來很眼熟,卻已經是過期的答案
回頭用新連線印出來的參數重新算一次:
1 | r1, r2 = 6900.768e3, 7167.955e3 |
第五次、也是最後一次機會:
1 | > 71.829 81080.728 |
總之這題偷懶沿用上一輪的答案
Flag
1 | STARPWN{h0hm4nn_tr4nsf3r_1nt3rc3pt} <- V1 |
心得
- 算重力參數不要相信課本常數,直接從題目給的數字反推。 圓形軌道上
mu = v² · r這個關係式永遠成立,用它反推出來的mu自動跟題目內部用的地球模型一致,不用猜測題目作者到底是用哪一版的地球半徑或 GM 常數。 - 伺服器的「部分正確」回應是很精準的除錯資訊。 只有 wait time 被判錯、Δv 卻悄悄通過,這代表轉移軌道本身的物理算式(半長軸、vis-viva、轉移時間)已經確認沒問題,問題精確縮小到相位角的方向定義上,不需要重新懷疑整個算法。
- 相位角的正負號慣例,是這類交會問題最常見的陷阱。 課本公式假設了某種特定的角度量測方向跟基準,題目給的「裸的」相位角數字如果沒說清楚定義方式,就要有心理準備去試試看方向相反的版本——兩者恰好差了一個會合週期,一個算錯了通常下一步就是換方向試另一個。
- 同一題的「V2」不代表數字也一樣。 就算是同一套程式碼、同一種公式,只要是每次連線都重新隨機出題的服務,舊連線算出來的正確答案在新連線裡就是過期資料——而且伺服器通常會老實告訴你「哪一項錯了」,這個訊號比自己盲猜要可靠得多,該做的是回頭用當下畫面印出來的數字整組重算,而不是只調整自己正在盯著看的那個數字。






