奧林匹亞資訊班
3/6
講師:吳崇維(wayne)
課前練習 (1)!
小蟲 & 小維正在玩一種抓石塊的遊戲 -- 規則是這樣的:
地上現在有兩堆石頭,分別有 n 個與 m 個石頭
兩人會一直輪流拿石頭,小蟲先拿,並且一次只會拿2個 ; 小維後
拿,一次只會拿3個,並且每次都只能從同一堆石頭拿取。
這樣一直輪流拿,直到有一個人拿不了石頭,他就輸了!
(Ex : 要是輪到小維,兩堆各剩一個和兩個,他就不能拿任何一堆了)
現在兩人玩這個遊戲的策略是:每次都拿石頭個數多的那一堆
現在給你兩堆石頭的個數,請你輸出誰會贏呢?
Sample Input : 5 7
Sample Output : First Player Win
課前練習 (2)!
之前提過回文:正著看以及倒著看都一樣的字串
現在給你一個正整數(請你用 %d 讀取),請你判斷他是不是回文呢?
Sample Input : 121
Sample Output : True
Sample Input : -121
Sample Output : False
課前練習 (3)!
課前練習 (3)!
課前練習 (3)!
小維要吃午餐,可是因為疫情,他只好在家叫foodpanda
他的帳戶裡面還有N塊錢,並且共有價格為a1, a2, a3 ...
等K種餐點選項
現在food panda有推出優惠活動,100元以上的餐點打8折
請問小維最多能點幾份餐點呢?
Sample Input:
第一行是N K 分別代表小維有多少錢,以及有幾種餐點
接著第二行會有K個數字,代表餐點的原始價格(不會按照順序)
Ex:
100 3
20 81 100 (Hint : #include <algorithm>)
Output: 2 ( sort(arr, arr+k) 可以排序 )
課前練習 (4)!
Graph 圖論
何謂一張圖?
一張圖是由一些頂點 (vertex)
以及一些邊 (edge) 所組成
一條邊會連結兩個頂點 -- 我們
通常用這些點邊的關係來表示
資料們的結構關係!
常用圖用語
有向圖 :有方向的圖,如右
無向圖 :邊都沒有方向
邊權:有時候每一條邊會被賦予權重,可以想像成地圖上的『距離』
路徑:從一個頂點走到另一個頂點
閉路:起點與終點相同的路徑
連通圖:任意兩個頂點都有一條路徑連接著
樹:連通圖,並且不存在閉路(短期不會碰到,不過這是圖論的一大分支)
今日目標
我們如何儲存一張圖?
圖的儲存 (1)
以右圖為例共有五個頂點,我們分別以0, 1, 2, 3, 4來代表他們
而邊就是他們兩兩之間的關係
我們要怎麼儲存邊呢?
最直覺的方法:鄰接矩陣
白話來說就是一個二維的陣列
如果arr[i][j] = 1 代表i, j兩點之間有連接
如果arr[i][j] = 0 代表沒有
圖的儲存 (1)
練習!
試試看在紙上寫出這個二維陣列的
內容是什麼吧!
圖的儲存 (1)
接著我們轉化成程式
有以下的輸入,第一行是n, m
n 是頂點個數
m 是邊的個數
接下來會有m行,每行會有兩個整數
代表這兩個頂點中間有邊!
把這樣的輸入轉化成陣列的表示方式吧!
圖的技巧 --DFS
說完了圖的基本概念,我們接下來要
實際的接觸一些技巧
第一個就是DFS (Depth-First Search)
什麼意思呢?我們可以看看例子
圖的技巧 --DFS
DFS就是在一張圖上搜尋的時候
優先的先"往下"搜尋
這樣的搜尋法可以用遞迴函數實現
我們先從例題可以更清楚概念
DFS例題
現在給你n個整數
a1, a2, a3 ... , an, 以及一個數k
請問能否判斷其中幾個數值的和
可不可以剛好等於k呢?
這題雖然與圖論無關,但是是闡述
DFS相當好的題目。
DFS例題
現在來作一題跟圖有關的!
給你一張圖,請問這張圖能不能
完成二著色呢?
二著色就是每一個頂點都有紅或
藍其中一種顏色,但是相鄰的兩
個頂點顏色不能相同。
圖的儲存 (2)
先前的圖儲存法有一個缺點:就是所佔的空間太大的,需要O(n^2)
所以有另一個(也是最常用的)儲存方法
叫做鄰接串列
圖的儲存 (2)
什麼意思呢?
假設現在頂點0有連到1, 3, 4
那麼我會有一個類似二維陣列的結構
arr 是類似二維,arr[0]是一維
arr[0] = [1, 3, 4]
只儲存有連出去的
避免的不必要的浪費
(詳圖例見版書)
圖的儲存 (2)
所以我們要引進 vector 的資料結構
vector是可以動態改變陣列大小的陣列
也就是說一般的陣列都要先宣告大小,例如 int arr[100];
但是vector要用多少就用多少,空間不會浪費!
圖的儲存 (2)
所以我們要引進 vector 的資料結構
vector是可以動態改變陣列大小的陣列
也就是說一般的陣列都要先宣告大小,例如 int arr[100];
但是vector要用多少就用多少,空間不會浪費!
圖的儲存 (2)
使用vector,必須先引進
#include <vector>
宣告的時候為
vector<int> arr;
我們可以作 arr.push_back(1);
來將1這個元素推到arr的尾端!
vector的所有操作:https://mropengate.blogspot.com/2015/07/cc-vector-stl.html
圖的儲存 (2)
練習:使用vector來儲存一張圖的所有邊吧!
一樣第一行是n, m代表頂點與邊
接下來m行是每一條邊的兩個頂點
圖的儲存 (2)
練習:使用vector來儲存的圖來解決
二著色問題!
這已經很接近正規決賽的題目要求了
因為我們需要很好的時間複雜度,所以不可以用二維陣列來儲存圖。
FeedBack!
一起努力快樂寫程式吧!
圖論
By Wayne Wu
圖論
- 70