APCS 動線安排 (zerojudge g596)
你是一個遊樂園展場的管理員,展場是一個 \(m\times n\) 的矩形,可以使用木樁和線來排動線,你可以有兩種操作
- 加入木樁 r c 0
加一木樁在,並且向他的上下左右盡量找離最近的木樁連線,題目保證 \((r,c)\) 上一定沒有木樁,若 \((r,c)\) 有線經過則先將那些線拆掉後再來連線
- 移除木樁 r c 1
\((r,c)\) 拔木樁,並把他的線也拔掉, 保證 \((r,c)\) 上一定有木樁
總共有 \(h\) 次操作,輸出過程中有線和有木樁佔據空間的面積最大是多少,以及 \(h\) 次操作後有線和有木樁佔據空間的面積
解題思路:
狀態
每個格子存在的 5 種狀況 (空的、木樁、直線、橫線、交線) 用五個數字表示:0、1、2、3、5 (交線用 5 是因為後面實作連線和拔線的時候,可以直接用加或減,讓一條線的狀態轉移到交線,或將交線的狀態轉移到一條線)
程式碼
1 | int cnt() { |
拔木樁 先把該點木樁拔掉 (設為 0),再往四個方向找線,如果有線就將跟目前前進方向相同的線拔掉 (假設目前是往上找,如果確認這個點是線,那就將那個點的狀態減 2,因此該點是直線會變 0 (空的),交線則變 3 (橫線))
程式碼
1 | void rm(int x, int y) { |
建木樁 先將指定點的狀態設為 1,接著往四個方向找木樁,如果確認有木樁就建線,建線的作法跟拔線相似 (假設目前是往上找,如果目前點的狀態是 2 (直線) 或 0 (空的) 那就設成 2,如果狀態是 3 (橫線) 就設成 5 (交線),而如果狀態是 5 就不改變)
程式碼
1 | void build(int x, int y) { |
主程式 有前面那些函式後就簡單了,讀輸入然後呼叫建木樁或拔木樁,最後再輸出答案就完成了
程式碼
1 | signed main() { |
🌟
要注意的是線有分成直向和橫向,直的被刪掉之後橫的不會被刪掉,若一個格子內同時存在直線和橫線,在刪掉其中一個的時候,另一個方向的線還要繼續存在,另外就是新的木樁放上去之後,不管原先那個格子上的線是什麼,會直接被刪掉,然後再由那個木樁往四個方向連線 (我就因為這樣修了兩次 bug🥲)
1 |
|