1 / 48

主題 : 模擬題與其他問題

主題 : 模擬題與其他問題. 模擬題 其他問題 倒水問題 貼郵票問題 四則運算 例題講解 : H.92.3 多變形的辨識 歷年題目. 模擬題. 殺人問題 曆法轉換 Robot 撲克牌 猜數字 Life Game Loop Detection. 例 : A.305 Joseph. 有 k 個好人 (1 ~ k) 與 k 個壞人 (k+1 ~ 2k) 排成一圈,從編號 1 開始數,每次殺第 m 個人,請問要讓所有壞人比所有好人先死的 m 最小為多少? 0 < k < 14. k = 3. ×. 2. 2. 3. 1.

yoland
Download Presentation

主題 : 模擬題與其他問題

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 主題: 模擬題與其他問題 • 模擬題 • 其他問題 • 倒水問題 • 貼郵票問題 • 四則運算 • 例題講解: H.92.3 多變形的辨識 • 歷年題目

  2. 模擬題 • 殺人問題 • 曆法轉換 • Robot • 撲克牌 • 猜數字 • Life Game • Loop Detection

  3. 例: A.305 Joseph • 有 k 個好人 (1 ~ k) 與 k 個壞人 (k+1 ~ 2k) 排成一圈,從編號 1 開始數,每次殺第 m 個人,請問要讓所有壞人比所有好人先死的 m 最小為多少? • 0 < k < 14

  4. k = 3 × 2 2 3 1 3 1 × × × 4 6 4 6 × 5 5 m = 5 m = 4

  5. 解題技巧 • 在讀入 k 之前,先把 k = 1 ~ 13 的答案算出來並紀錄,接下來不管讀入任何 k 都直接查表印出答案即可 • 直接模擬 • 若 m % 2k  k 則此 m 不是答案,因為第一步就殺到好人 • 一步一步模擬直到所有壞人殺光或殺到好人為止

  6. 例: A.602 What day is it? • 給予日期 (m d y) 請問此日期的 weekday8 10 2004  Tuesday • 閏年規則: 若年份是 4 的倍數,且不為 400 的倍數則是閏年 • 曆法修正: 因為閏年修正的關係,所以 1752/9/02 的下一天是 1752/9/14

  7. 解題技巧 • 直接模擬 • 檢查給予的日期是否合法 • 看看今天的 weekday 往回推 • 小心閏年規則與曆法修正日期

  8. 例: A. 10500 Robot maps • 給一個 n × m 的地圖,地圖上有空格與障礙物,1  n, m  10 • 給予機器人的起始位置 (必定是空格),每次機器人會先讀取上下左右格子的資訊,接下來移動到第一個沒走過的格子(檢查順序是由上方開始順時針方向 ),一直到週圍都已走過或是障礙物為止 • 輸出機器人所偵測到的地圖

  9. ? ● ? ? ? ? ● x ? x ? ? ● ? ● ? x ? x ? ? ? ? x ? ? ? ? ? ● x ? ? ? ? ? ? ? ? ? ? x ● x ? ? ? ? ? ? ? ? ? ? x ? ? ? ? ? ? ? ? ? ?

  10. 例: A.131 The psychic poker player • 手上有五張牌,桌上有五張牌,可以換一次牌(從手上丟掉任意k 張,從桌上依序拿取 k 張),請問最大可以換到什麼牌 • 手上: 2H 2S 3H 3S 3C桌上: 2D 3D 6C 9C 10H最好的換法: 換兩張2H 2S 3H 3S 3C2H 2S 3H 3S 3C 2D 3D × ×

  11. 解題技巧 • 從換 0 張到換 5 張 • 不換牌 • 所有丟掉 1 張牌的可能組合 + 依序拿進 1 張 • 所有丟掉 2 張牌的可能組合 + 依序拿進 2 張 • … • 比較牌組大小時先比數字再比花色

  12. 例: A.296 Safebreaker • 猜 4 位數字遊戲,給予數行 (1~10) 猜數字的過程,請判斷有唯一解,無解,還是不只一組解 • xxxx A/B: xxxx 是這回合猜的數字,A 表示數字對且位子也對的數目,B 代表數字對但是位置不對的數目

  13. 9793 0/12384 0/26264 0/13383 1/02795 0/00218 1/0 • 答案: 3411

  14. 解題技巧 • 開一個大小為 10000 的陣列,對於每一組猜測都把不可能的數字標記掉 • 最後看剩幾組數字沒標記 • 0組: 無解 • 1組: 唯一解 • 多於 1 組: 不只一組解

  15. 例: A.457 Linear cellular automata • 給 40 個細菌培養皿,每個培養皿有自己的細菌濃度 (從 0 到 3),與濃度轉換公式 • 每天每個培養皿會根據昨天自己的濃度、左右兩個培養皿濃度及轉換公式得到新的濃度:denday j+1[i] = 公式(denday j[i] + denday j[i1] + denday j[i+1]) • 請列出所有培養皿從第 1 天到第 50 天的狀態

  16. 轉換公式: 0→1 1→1 2→2 3→0 4→1 5→3 6→3 7→2 8→2 9→0 0 0

  17. 解題方法 • 仔細閱讀題目敘述與假設 • 第一天第 20 個培養皿濃度是 1,其他皆為 0 • 假設在第 1 個左邊與第 40 個右邊各有一個濃度一直為 0 的培養皿 • 按照題目敘述與轉換公式逐日模擬並輸出

  18. 例題: W.96.1 20-30-40 • 給予一副牌,按照順序發成三疊 • 在發了任一張牌後,若任何一疊中,有(1)底部一張與最上面兩張 (2) 底部兩張與最上面兩張 (3) 底部連續三張加起來點數為 10、20 或 30,則把這三張牌拿起來進入手上牌疊 • 若某疊牌拿起三張後仍符合上述條件,則一直拿到不符合條件為止 • 若有某一疊的牌完全被拿光了,則以後不在往這疊發牌 • 請輸出最後結果: (1) 三疊牌都清空了 (2) 手上牌疊空了 (3) 進入無窮迴圈

  19. 進階技巧 – loop detection • 需要偵測是否有迴圈出現 • 方法一: 模擬比對 • 每跑出一個新狀態,就從頭開始再跑一次看是否出現過同樣的狀態 • 方法二: 紀錄狀態 • 把所有出現過的狀態記錄下來比對

  20. 模擬比對 // 這 function 用來模擬從狀態 a 發一張牌後的情況 state DispatchOneCard(state a); // 主要用來直接模擬比對的迴圈 while (not_win_lose) { now_state = DispatchOneCard(last_state); step++; CheckWinLose(now_state); pre_state = init_state; for (i = 1; i<step; i++){ if (pre_state == now_state) return; else pre_state = DispatchOneCard(pre_state); } }

  21. 紀錄狀態 • 可能的狀態數目在記憶體範圍內,則用列舉法 • 列舉所有可能的狀態,標記出現過的狀態 • 可能的狀態數目超過記憶體容量 • 狀態可以比較大小: 用 search tree紀錄所有出現過的狀態 • 狀態較難比較大小: 使用 hash value來加速尋找重複的狀態

  22. Search tree • 一開始, search tree 是空的,第一個出現的狀態成為 root • 每一個 tree node 上會代表一個狀態 • 在這個 node 的 subtree 中 • Left subtree: 比這個狀態小 (字典順序或編碼順序) 的狀態 • Right subtree: 比這個狀態大的狀態

  23. 例: ABCD 的組合 開始沒有狀態  tree 是空的 ACBD 產生狀態 ACBD,加入 tree 產生狀態 ABCC,加入 tree ABCC BADA 產生狀態 BADA,加入 tree 產生狀態 CCCB,加入 tree ACDD CCCB 產生狀態 BADB,加入 tree 產生狀態 ACDD,加入 tree BADB 產生狀態 ABCC,loop!!!

  24. Hash • 用一個多對一的 hash function h(x) 來把狀態 x 對應到既定範圍內的數字 • 不同的狀態可以對應相同的數字 • 同一個狀態必須對應同一個數字 • 每出現一個狀態,就檢查相同 hash value 的狀態裡是否有一樣的狀態

  25. 例: 0123的所有組合 • H(s1s2s3s4) = s1 + s2 + s3 + s4 0 1 2 3 4 5 6 7 8 9 10 11 12 1220 狀態 0002, H(0002) = 2 狀態 1220, H(1220) = 5 0002 0110 狀態 0010, H(0010) = 1 狀態 0110, H(0110) = 2 0010

  26. 儲存相同 hash value 的狀態 • 用 link list • Sorted list: insert 較慢,但搜尋較快 • Unsorted list: insert 快,但搜尋要看完 list • 用 search tree • 程式較複雜 • 效率介於上述兩者之間 • 建議用 hash + unsorted lists

  27. 倒水問題: A.571 Jugs • 給兩個罐子及其容量 A 與 B (A , B 互質),允許的動作是把某罐子清空或倒滿水,把某個罐子的水倒到另一個罐子裡直到一邊空了或滿了為止 • 給予一目標 N,請問最少的動作次數才能倒出 N 來

  28. 解題技巧 • 存在一組最佳解,不是 A 一直注滿 B 一直倒空,就是 B 一直注滿 A 一直倒空 • Hint: 一個罐子不會發生又被注滿又被倒空的情形

  29. 例: A = 5, B = 3, N = 4  注滿A  從 A 倒 B  清空B  從A 倒 B  注滿A  從A 倒 B  4 出現!!! B A

  30. 作法 • 把 A 注滿 • 從 A 倒 B • 若 B 滿,清空 B • 若 A 沒了,注滿 A • 檢查是否出現 N ,若無則重複以上步驟 • 把 A 與 B 的角色對調並重複上述步驟,取動作次數較少的即為答案

  31. 貼郵票問題: A.165 Stamps • 給 h 與 k (h + k  9),h 是總共可以貼的郵票張數,k 是面額種類,請幫忙決定用怎麼樣的面額,使得從 1 開始到 N 的所有數字都可以貼出來,並且 N 最大 • 例: h = 3, k = 2,則 1 與 3 可以貼出最大的 N面額 = {1, 2}, 可貼出 = {1, 2, 3, 4, 5, 6} 面額 = {1, 3}, 可貼出 = {1, 2, 3, 4, 5, 6, 7, 9} 面額 = {1, 4}, 可貼出 = {1, 2, 3, 4, 5, 6, 8, 9, 12}

  32. 解題技巧 • 暴法展開填表法 • 用暴力法展開所有可能的幣值 • 若已知面額,則可用填表法來得知 N 面額 1 1 一定要 面額 1, 2 面額 1 2 要不要 面額 1, 2, 3 面額 1, 2 面額 1, 3 面額 1 3 要不要

  33. 實作技巧 • 在 recursive 過程中使用一陣列來記錄現在能貼的數字與最小使用張數,在加入新的面額後可以很快得知新的結果 N 1 2 3 4 5 6 面額 1,2 最小 張數 1 1 2 2 3 3 N 7 8 9 1 2 3 4 5 6 面額 1, 2,3 最小 張數 3 3 1 1 1 2 2 2

  34. 如何避免無窮的 recursive? • 已經使用 h 種面額時不再往下長 • 在決定面額 m 時,若先前決定的最大 N 為 m–1,則面額 m 非使用不可 • 例: 若在決定面額 6 時,之前所用的面額只能湊出 1, 2, 3, 4, 5,則面額 6 非用不可,不然往後因為面額都比 6 大,不可能湊出 6 • tree 的高度  k2h

  35. 四則運算式 • 一般我們使用的四則運算式稱之為 infix 表示法,因為運算元是在運算子中間5 + 8  3 – ( 4 / 2 ) + 9 • infix 比較不適合用電腦做運算,因為有運算順序 (先乘除後加減) 與括號,使得我們要記錄之前的運算元與運算子

  36. Posfix 表示法 • 運算元在運算子之後,沒有運算順序與括號的問題,較適合電腦運算,只需一 stack 來記錄運算子 • 規則: 看到運算元則對之前兩個運算子做運算,結果會成為新的運算子infix: A + B  C – ( D / E ) + 9posfix: ABC+DE/–9+

  37. 實作 • 用一 stack 存放,由左至右 scan 運算式 • 運算子: push • 運算元: pop 兩個運算子運算,push結果 例: ABC+DE/– C B T1 = B  C push(A) push(B) push(C) T1 = B  C push(T1) T2 = A + T1 push(T2) A T2 = A + T1

  38. Infix 轉換 posfix (無括號) • 用一 stack 存放運算元,由左至右 scan • 運算子: 直接輸出 • 運算元: 若運算順序小於等於 stack 最上面的運算元,則 pop 並輸出到大於為止,然後就 push 此運算元 infix: A+BC–D/E  pop(), pop(+) push(–) push() 輸出 A push(+) 輸出 B 輸出 C – +  DE/– + A B C Posfix:

  39. Infix 轉換 posfix (有括號) • 一樣由左至右 scan • 遇到左括號,push • 遇到右括號,pop 直到左括號為止 (括號不用輸出),也不用 push 右括號 • 其餘同上一頁,在 pop 過程中遇到左括號則停止 pop / + Infix: A  ( B/C + D) (  D Posfix: A B C + / 

  40. 例: H.92.3 多邊形的辨識 • 一有 105點的圖形,每個點按規則編號,給數個點,判斷這數個點是否構成直角三角、正方、長方、平行四邊或六角形 15 10 14 6 9 13 3 5 12 8 1 2 4 7 11

  41. 範例 28 6, 13, 15  直角三角形 27 21 1, 2, 5, 3  正方形 26 15 20 10 14 19 25 19, 25, 26, 20  平行四邊形 24 6 9 13 18 11, 16, 23, 24, 18, 12  六邊形 3 5 12 17 23 8 8, 12, 18  不是直角三角形 22 1 2 4 7 11 16

  42. 標示座標 • 按照順序幫每個點標示座標 • 按斜列順序標示 4 3 2 1 0 第 3 斜列的第一點 (4) 座標: (2, 0) 第二點 (5) 座標: (1, 1) 第三點 (6) 座標: (0, 2) 15 10 14 6 9 13 第 i 斜列的第一點座標: (i–1, 0) 第二點座標: (i – 2, 1) 第三點座標: (i – 3, 2) ( x 座標遞減, y 座標遞增) 3 5 12 8 1 2 4 7 11 0 1 2 3 4 x座標

  43. 解題技巧 • 因為圖形中沒有 / 方向的線段,因此任何合法的圖形必定存在一左上點(x 座標最小,y 座標最大) 28 27 21 26 15 20 10 14 19 25 24 6 9 13 18 3 5 12 17 23 8 22 1 2 4 7 11 16

  44. 直角三角形 • 以左上點為基準點,有兩種可能 • 因為斜線的斜率是 1,所以是等邊直角三角形 (x+a, y) (x, y) (x, y) (x, y–a) (x+a, y–a) (x+a, y–a )

  45. 正方形與長方形 (x+a, y) (x, y) (x+b, y) (x, y) (x, y–a) (x+a, y–a) (x, y–a) (x+b, y–a)

  46. 平行四邊形 (x, y) (x+a, y) (x, y) (x+b, y–b) (x, y–a) (x+b, y–b) (x+a+b, y–b) (x+b, y–b–a)

  47. 六邊形 (x, y) (x+a, y) (x, y–b) (x+a+c, y–c) (x+a+c, y–b–c) (x+c, y–b–c)

  48. 歷年題目 • 練習題 • A.402M*A*S*H • http://acm.uva.es/p/v4/402.html • A.10315 Poker Hands • http://acm.uva.es/p/v103/10315.html • A.727 Equation • http://acm.uva.es/p/v106/10600.html • A.571 Jugs • http://acm.uva.es/p/v5/571.html • A.165 Stamps • http://acm.uva.es/p/v1/165.html • 挑戰題 • A.180Eeny Meeny • http://acm.uva.es/p/v1/180.html

More Related