# 10/22 APCS思路&想法 :thinking_face: --- # 第一題 機械鼠 :rat: ---- - 題目內容: 1. 有一隻勞贖在一個一維的路上(像數線一樣) 2. 在這條路上有n個食物 :cheese_wedge: 3. 老鼠會往食物多的方向走(左or右)(一維) :left_right_arrow: - 題目要求: 輸出老鼠吃到的食物數量跟最後的位置 ---- ### How to do 勒? :confused: 簡單來解的話這題就維護4個變數就好 1. Re(老鼠最右邊的食物位置) 2. Le(老鼠最左邊的食物位置) 3. Rnum(老鼠右邊食物數量) 4. Lnum(老鼠左邊食物數量) ---- ```cpp= #include <bits/stdc++.h> using namespace std; #define int long long #define ios ios_base::sync_with_stdio(0);cin.tie(0) #define endl '\n' #define debug(x) cerr<<#x<<x<<'\n'; int Re, Le, Lnum, Rnum; int x, n, in; //題目保證n是奇數 signed main(){ cin >> x >> n; Re = x; Le = x; for(int i=0; i<n; i++) { cin >> in; if(in > x){ Rnum++; if(in > Re) Re = in; } if(in < x) { Lnum++; if(in < Le) Le = in; } } if(Rnum > Lnum) cout << Rnum << " " << Re << endl; else cout << Lnum << " " << Le << endl; } ``` ![](https://hackmd.io/_uploads/B1wG6KVzT.png) --- # 第二題 卡牌遊戲 :flower_playing_cards: ---- #### 題目內容: 1. 有一個桌遊,場上有n\*m個位置可以放卡片 2. 每張卡片上都有數字 3. 在 - ***兩張牌數字相同*** - ***兩張牌在同一行or列*** - ***兩張中間沒有被別種牌隔開*** - (P.S.沒有牌的空位置不算) 的情況下,玩家可以***拿走這兩張牌***,並得到數字大小的分數 4. 重覆到無牌可拿為止 ---- ### How to do 勒? - 不妨先想想如果你真的在玩這個桌遊會怎麼做 1. 看看場上有什麼牌 :face_with_raised_eyebrow: 2. 把一樣的拿掉 :negative_squared_cross_mark: 3. 重複 :repeat: 很多時候對於測資小的實作題這樣想挺有幫助的 :+1: ---- ## 一點想法: #### 拿過要消掉好煩先不理它 :smirk: - 開一個矩陣(array)存每格的卡 - 每次都掃過n\*m格的牌 - 對於每一張牌都往它的上、又、下、左看一次 - 找到一樣的就把它標成-1,並把score加上卡的點數 這樣一來,我們已經解決了上面的一、二點了 :+1: ---- ## 一些問題: :no_mouth: 1. 第三點怎麼辦,我怎麼知道要重複幾輪? 2. 拿走一些牌之後,萬一出現了新的可以消的怎麼辦? - ex: 1123325 - (2那組是在3那組削掉後才出現的) ---- ## 1解決の方法 - 針對不知道要做幾次的問題 設一個變數控制要不要繼續找 (bool flag) ```cpp= // 示意用only, pesudo code(偽代碼) while(flag) { flag = false; if(checkCards()) { takeCards(); flag = true; } } ``` ---- ## 2解決の方法 - 針對要跨過空位置找卡的問題 在往4個方向找時,如果看到的這個是0那就在往那個方向加找一次 ```cpp= // 示意用only, pesudo code(偽代碼) const int dx[4] = {0, 1, 0, -1}; const int dy[4] = {1, 0, -1, 0}; int c_x, c_y; // 現在的i跟j for(int i=0; i<4; i++){ int reach = 1; while(board[c_x + reach*(dx[i])][c_y + reach*(dy[i])] == -1) { reach++; } // 然後再判斷找到的牌是否點數相同 } ``` ---- 最後的小提醒: ### 寫這種會在二維陣列中查找、搜尋or更改的題要注意邊界的檢查 :exploding_head: ---- ## Answer Code #### powered by Stanley Hsu :cat: ```cpp= #include <bits/stdc++.h> #define boost ios::sync_with_stdio(0);cin.tie(0) using namespace std; int main () { boost; const int dx[4] = {1,0,-1,0}; const int dy[4] = {0,1,0,-1}; int n, m, sum = 0, times, y, x; bool changed = true; bool done = false; cin >> n >> m; int arr[n][m]; for (int i =0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> arr[i][j]; } } while(changed) { changed = false; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (arr[i][j] == -1) continue; for (int k = 0; k < 4; k++) { done = false; times = 1; while (1) { y = i+dy[k]*times; x = j+dx[k]*times; if (y >= 0 && y < n && x >= 0 && x < m) { if (arr[y][x] == arr[i][j]) { changed = true; sum += arr[y][x]; arr[y][x] = -1; arr[i][j] = -1; done = true; break; }else if (arr[y][x] == -1){ times++; }else{ break; } }else{ break; } } if (done) break; } } } } cout << sum; } ``` --- # 第三題 搬家 :derelict_house_building: ---- #### 題目內容: 1. 在一個n\*m的地圖上,有一些水管 2. 題目會輸入地圖的情況: - F: (可以接)右和下 - H: 左和右 - 7: 左和下 - I: 上和下 - X: 上、下、左和右 - L: 右和上 - J: 左和上 - 0: 沒有水管 ---- ![](https://hackmd.io/_uploads/HJ4JdgrMT.png) ---- ## 題目要求: ### 找出最大連在一起的水管區塊,並輸出它的水管數目 ---- ### 好像!跟之前教的BFS、DFS好像! 他就是之前庭院裡的水池那種題目的變化型 #### 加上檢查連不連得起來 跟記一下長度就好ㄌ --- 第四題我還沒交過你們XD
{"title":"10/22 APCS思路","description":"View the slide with \"Slide Mode\".","contributors":"[{\"id\":\"7e7eccf7-4271-4dfb-a0ab-96cc5f708184\",\"add\":6927,\"del\":2352}]"}
    122 views