###### tags: `APCS` `M931` `C` # M931 ## 題目描述 ### 內容 有 $n$ 個角色,每個角色有攻擊力和防禦力。 角色的**能力值**是攻擊力和防禦力的**平方和**,輸出**能力值第二大**的**攻擊力**和**防禦力**數值。 保證每個角色的能力值相異。 ### 輸入說明 第一行包含一個整數 $n$ $(3$ ≤ $n$ ≤ $20)$,表示有多少個角色。 接下來的 $i$ 行,每行包含兩個整數 $a_i$ 和 $d_i$ ,表示第 $i$ 個角色的攻擊力和防禦力。 ### 輸出說明 輸出兩個整數,表示能力值第二大的角色的攻擊力和防禦力。 ### 評分說明 第一題組$(60$ %$)$:滿足 $n = 3$。 第二題組$(40$ %$)$:無額外限制。 ### 範例 #### 測資 $1$: 3 3 1 5 2 1 4 #### 輸出 $1$: 1 4 #### 測資 $2$: 6 6 6 1 3 8 6 5 4 2 8 7 2 #### 輸出 $2$: 6 6 #### 測資 $3$: 5 34 35 84 32 39 79 59 89 59 31 #### 輸出 $3$: 84 32 *** ## 題目思索 我第一眼看到是找最大值,但發現並不是,而是找出能力值第二高的並輸出其攻擊力跟防禦力。 所以我的想法是先讀進 $n$ 個角色的攻擊力 $a_n$ 與防禦力 $d_n$,同時判斷是否為最大能力值的角色,並記錄下其能力值 $max$ 與序位 $val$。 ```c for(int i = 0; i < n; i++){ scanf("%d%d", &a[i], &d[i]); if((a[i] * a[i] + d[i] * d[i]) > max){ //如果第i個的能力值比之前的max值大,則更新val與max的值 val = i; max = a[i] * a[i] + d[i] * d[i]; } } ``` 將其攻擊力及防禦力歸零。 ```c a[val] = 0; d[val] = 0; max = -1; ``` 再重新使用迴圈判斷一次,這次所找出的則是第二大能力值的角色,再將其攻擊力跟防禦力輸出即可。 ```c for(int i = 0; i < n; i++){ //與前次迴圈的邏輯相同 if((a[i] * a[i] + d[i] * d[i]) > max){ val = i; max = a[i] * a[i] + d[i] * d[i]; } } printf("%d %d", a[val], d[val]); ``` *** ### 初稿程式碼 ```c= #include <stdio.h> int main(){ int n, max = -1, val; scanf("%d", &n); int a[n], d[n]; for(int i = 0; i < n; i++){ scanf("%d%d", &a[i], &d[i]); if((a[i] * a[i] + d[i] * d[i]) > max){ val = i; max = a[i] * a[i] + d[i] * d[i]; } } a[val] = 0; d[val] = 0; max = -1; for(int i = 0; i < n; i++){ if((a[i] * a[i] + d[i] * d[i]) > max){ val = i; max = a[i] * a[i] + d[i] * d[i]; } } printf("%d %d", a[val], d[val]); return 0; } ``` ### 測試結果 ![m931-test](https://hackmd.io/_uploads/BkvPwDqKT.png) *** ## 成果 ### 程式碼 ```c= #include <stdio.h> int main(){ int n, max = -1, val; scanf("%d", &n); int a[n], d[n]; for(int i = 0; i < n; i++){ scanf("%d%d", &a[i], &d[i]); if((a[i] * a[i] + d[i] * d[i]) > max){ val = i; max = a[i] * a[i] + d[i] * d[i]; } } a[val] = 0; d[val] = 0; max = -1; for(int i = 0; i < n; i++) if((a[i] * a[i] + d[i] * d[i]) > max){ val = i; max = a[i] * a[i] + d[i] * d[i]; } printf("%d %d", a[val], d[val]); return 0; } ``` ### 解題 ![m931_final](https://hackmd.io/_uploads/B1qMtv9tp.png) *** ## 反思 這次解題使用了較直觀的方式,也就是透過兩次迴圈,第一次先找出最大並去除掉,再透過第二次找出第二大即可,那如果是要排序的話也可以,但我選用的方法更淺顯易懂,邏輯層面越簡單,若有錯誤也越容易改動,對於限定時間內的解題有更大的好處。 ### 心智圖 ![m931_mindmap](https://hackmd.io/_uploads/SJ4ho8cta.png) *** ## 題目來源 [m931. 1. 遊戲選角 (From Zero Judge)](https://zerojudge.tw/ShowProblem?problemid=m931) ###### 2024-1-21 完成編寫此文