奧林匹亞資訊班

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