前兩次上課還沒來得及補齊,先來紀錄一下第三週的內容
上課內容
這一週的主題是基礎圖論、淹水問題(BFS)還有Heap!把這幾個單元排在一起真的是負擔很重QQ
- 基礎圖論之前就有聽過,所以在寫題目感覺還好,不會很吃力
- Heap則是我第一次接觸到的資料結構,當周上課前把影片(介紹Binary Heap)之後,上課就直接講合併Heap、黑魔法Heap、左偏樹等等把我電爛的東西
- 淹水問題,上課沒有特別介紹,因為講師說他不喜歡Flood Fill 演算法所以只講了可以用 dx 和 dy 表示上下左右的方位,其他的都沒講,只能自己看影片了呀~
上機作業
Heap 練習
題目連結
刻一個heap嘛,不想刻就call stl( std::priorityqueue 就不放上來了)
自己刻一個binary heap ,沒有想象中的簡單,有些細節會不小心漏掉
1 |
|
哪裡有卦,哪裡就有源(TOJ 1101)
題目連結
明顯的二分圖水題喔~
用 dfs 把經過的點標出黑白,過程中如果遇到問題就表示非二分圖了
1 |
|
喵喵抓老鼠
題目連結
這一題是用BFS找最短路徑,因為沒有權重,所以可以直接用BFS看多久會最先走到老鼠
x y 座標原本用2個queue 分別存x跟y ,沒想到MLE了,後來改用struct,還是MLE!!
不過在27行的地方有一個Bug,害我找了好久…去問了電神,才發現 visit 應該要在push 的時候就紀錄了,不要等到pop的時候,不然很多重複的會被push 進去(簡單來說,一個位置只能被push一次)
1 |
|
庭院裡的水池
題目連結
看圖形有幾個連通圖的判斷的水題,可以用dfs 或bfs 做,小心index不要戳到負的
BFS作法
1 |
|
DFS作法
1 |
|
比較上面兩種方法的複雜度
BFS明顯優於DFS 啊!(遞迴本身來說就很耗記憶體?!應該是這題特殊的原因,不然應該用DFS 較優)
染色遊戲—台北縣98資訊學科能力競賽
一題好題勝過百題水題
現在終於體會到這一句話的精髓!這是一題難題呀(neoj的測資很緊)
首先先看顏色儲存的方式
如果我想要讓混色時一個運算進行,那要如何以數字形式儲存顏色就顯德相當重要
可以發現,用加法並不是個粉好的方法,因為顏色的數字有可能超過7
因此可以用取OR的方式來完成:
YELLOW : 001
BLUE : 010
GREEN : 011
RED : 100
ORANGE : 101
PURPLE : 110
DARK(BLACK) : 111
如果以這樣的編碼方式,剛剛好可以以OR運算來就可以模擬染色(這應該只能用觀察出來吧)
有了顏色的編碼方式之後,接下來就是處理點擴散的問題
由 $n<=1000$ 可知,如果要用2個for迴圈走訪整個畫布是不可行的
因為這樣就已經$10^6$ 多幾個常數就TLE了。
不能走訪每一個點,就只能好好的把要看的點push進queue裡面
每一次針對要找的節點,就能節省不必要的運算
最後,要怎麼維護點呢?
用一個struct 儲存,除了座標之外,就是出現的時間還有顏色
我遇到TLE 或 WA的BUG:
- 用 $n^2$ 掃描整個畫布—TLE
- push進一個struct時要在名字部分括號起來:
1 | queue<node> q; |
- 沒有加上遇到減少就break的條件,所以每一次都必須要整個畫布都變成黑色才會輸出—TLE
- 沒有紀錄一個點有沒有被三原色走過,一個點可能被走過很多次—TLE
- 邊界要好好維護,一個較方便的作法,讓index都從1開始,這樣相加相減變成-1 時才不會RE
- 時間優化:明顯知道答案(如問D的情況),就直接輸出$n^2$就好
1 |
|
手寫作業
這一週的手寫作業是介紹c++ 的記憶體使用方式,什麼變數應該會被存在什麼位置之類的,heap 與stack 還有虛擬記憶體,以及為什麼有時候寫dfs遞迴下去會RE的問題(我是還沒有遇過啦)
總之終於沒有數學證明題了!
今天段考果然炸裂了QQQQQQQ