2023 11 ITSA === ## 前言 這是我第一次參加ITSA,前幾題難易度適中,只有第三題沒看懂題意,卡比較久,其他題都沒花太多時間,整體考試時間3個小時也算充裕,不過賽前要記得先測試考試用的PS2,下面整理了這次前五題的題解 ## Problem 1. 字元計算 ### 題目 問題描述: 現在有多個字元,請寫一個程式,根據輸入的字元,統計 a-z 各字元出現次數。 輸入說明 第一行有 1 個正整數 N(1 ≤ N ≤ 1,000),表示共有幾個字元,接著會有 N 行,每 行為一小寫字元 (a-z)。 輸出說明: 根據輸入的字元,根據字元的排序 (a-z) 顯示各字元的出現次數,如果字元次數為 0 次則不須顯示,最後會有換行。 ### 解題思路 - 用字串`s`存a-z - 每一筆輸入對照字母後用陣列`d`紀錄字母出現次數 ```cpp== #include <iostream> using namespace std; int main() { int n,k,i,t=0,d[26]; cin>>n; char j; string s="abcdefghijklmnopqrstuvwxyz"; for(i=0;i<26;i++) d[i]=0; for(i=0;i<n;i++) { cin>>j; k=j-'a'; //把字元轉成ascii code再到陣列儲存 d[k]++; } for(i=0;i<26;i++) { if(d[i]!=0) { cout<<s[i]<<' '<<d[i]<<endl; } } } ``` ## Problem 2. 漏水 ### 題目 問題描述: 小和尚想到山下挑水上來裝滿蓄水池,但蓄水池被老鼠咬了一個小洞,小和尚不知情 的依舊維持他今日的挑水工作,假設小和尚每次可以挑 R 單位的水上來,但是在小和尚再次 下山到上山的時間,蓄水池會漏出 D 單位的水,請問小和尚要花多久才能裝滿蓄水池。 (下山挑水加上山為 1 小時) 。 輸入說明 每組測試資料 3 行, 第一行有 1 個浮點數 N(0 < N < 10,000),代表蓄水池的滿水單位。 第二行有 1 個浮點數 R(0 < R < N < 1,000),代表小和尚每次可填入的水量。 第三行有 1 個浮點數 D(0 < D < R),代表小和尚再次下山到上山時,蓄水池漏出的水單位。 輸出說明: 計算小和尚要花多久才能裝滿蓄水池,最後會有換行。 ### 解題思路 - 輸入有小數點,所以要用`float`存 - 用`while`迴圈計算要多久會滿水 ```cpp= #include <iostream> using namespace std; int main() { float a,b,c,d=0,t=0,i; cin>>a>>b>>c; while(1) { d+=b; //紀錄水池水量 if(d>a) //檢查是否滿水 { cout<<t; break; } d-=c; //減掉流走的水 t++; //計算次數 } } ``` ## Problem 3. 排 7 ### 題目 問題描述: 排 7 是一個多人的撲克牌遊戲,其規則為,玩家擁有♥7 者必須先出牌,之後玩家輪 流出牌;出牌方式必須接續同花色且依照數字順序(往上由7至 K,往下由6至 A),或者 發出其他花色的 7,直到所有人用完手牌為止。舉例而言,有人出♥7,下一位玩家必須發出 ♥6 或♥8,也可發出♠7、♣7 或♦7;當有人沒辦法出牌時,必須選擇從手上覆蓋一張牌來略 過這次出牌機會,此牌到遊戲結束前不可明示。遊戲結束時計算覆蓋牌點數的總和,最多的 人最輸,但是從頭到尾都覆蓋牌的人算最贏。 請寫一個程式,根據手上的牌,以及牌桌上已經出過的牌,判斷目前自己手上有哪些 牌可以出。 輸入說明: 第一行有 1 個正整數 N(1 ≤ N ≤ 20),表示牌桌上已經出過的撲克牌數量,第二行 會有 N 個正整數 P(0 ≤ P ≤ 52),每個整數中間用 1 空格隔開,每個正整數都表示 1 張 牌,每個整數中間用 1 空格隔開,如下所示: 梅花♣ : 1~13 =數字 0~12 方塊♦ : 1~13 =數字 13~25 紅心♥ : 1~13 =數字 26~38 黑桃♠ : 1~13 =數字 39~51 第三行有 1 個正整數 H(1 ≤ N ≤ 20),表示手上牌的數量,第四行會有 H 個正整 數,表示手上的每張牌,每個整數中間用 1 空格隔開, 例如,目前已經出過的牌為♣7 ♦7 ♥7 ♠7 手上牌為♣1 ♦2 ♦6 ♦12 ♥11 ♠4 ♠8,則 為: 4 6 19 32 45 7 0 14 18 24 36 42 46 輸出說明: 輸出目前自己手上可以出牌的數量。 最後會有換行。 ### 解題思路 - 陣列`d`紀錄桌上已出過的牌 - 陣列`r`記錄手牌 - 一個`if`判斷是否可以接牌 - 另一個判斷是否可出其他花色的7 ```cpp= #include <iostream> #include <utility> using namespace std; int main() { int a,b,c,t=0,i,j; string s; cin>>a; int d[a]; for(i=0;i<a;i++) { cin>>d[i]; } cin>>b; int r[b]; for(i=0;i<b;i++) { cin>>r[i]; for(j=0;j<a;j++) { if(r[i]==d[j]+1||r[i]==d[j]-1) t++; //判斷牌是否可接在前後 if(d[j]==6||d[j]==19||d[j]==32||d[j]==45) { if(r[i]==d[j]+13||r[i]==d[j]-13) //判斷能不能出其他花色的7 { t++; } } } } cout<<t; } ``` ## Problem 4. 會員資料查詢 ### 題目 問題描述: 現在有會員資料如下: | 會員編號 | 姓名 | 類別 | | -------- | -------- | -------- | | 123 | Tom | DTGD | | 456 | Cat | CSIE | | 789 | Nana | ASIE | | 321 | Lim | Dba | | 654 | Won | FDD | 請您寫一系統,可輸入關鍵字與指定搜尋的項目,可以撈出會員的資料。 ※搜尋方式採精準搜尋:關鍵字必須與要搜尋的資料完全一樣。(不分大小寫) 輸入說明 第一行有 1 個正整數 N(1 ≤ N ≤ 10),代表有 N 個指令,接著會有 N 行,每一行 有兩個參數,第 1 個參數代表要指定搜尋的項目,其中 1 表示要查詢會員編號、2 表示姓 名、3 表示類別;第二個參數代表要搜尋的關鍵字。 輸出說明: 把找到的那個會員依序印出他的會員編號、姓名、類別,兩兩間有 1 個空白隔開。 最後會有換行。 ### 解題思路 - 這題只有五個資料,所以我直接用五個if判斷並輸出 ```cpp= #include <iostream> using namespace std; int main() { int a,b,c,t=0,i; string s; cin>>a; for(i=0;i<a;i++) { cin>>b; if(b==1) { cin>>c; if(c==123) { cout<<"123 Tom DTGD"<<endl; } else if(c==456) { cout<<"456 Cat CSIE"<<endl; } else if(c==789) { cout<<"789 Nana ASIE"<<endl; } else if(c==321) { cout<<"321 Lim DBA"<<endl; } else { cout<<"654 Won FDD"<<endl; } } else if(b==2) { cin>>s; if(s[0]=='T'||s[0]=='t') { cout<<"123 Tom DTGD"<<endl; } else if(s[0]=='C'||s[0]=='c') { cout<<"456 Cat CSIE"<<endl; } else if(s[0]=='N'||s[0]=='n') { cout<<"789 Nana ASIE"<<endl; } else if(s[0]=='L'||s[0]=='l') { cout<<"321 Lim DBA"<<endl; } else { cout<<"654 Won FDD"<<endl; } } else { cin>>s; if(s[0]=='D'&s.length()==4||s[0]=='d'&s.length()==4) { cout<<"123 Tom DTGD"<<endl; } else if(s[0]=='C'||s[0]=='c') { cout<<"456 Cat CSIE"<<endl; } else if(s[0]=='A'||s[0]=='a') { cout<<"789 Nana ASIE"<<endl; } else if(s[0]=='D'||s[0]=='d') { cout<<"321 Lim DBA"<<endl; } else { cout<<"654 Won FDD"<<endl; } } } } ``` ## Problem 5. 村莊距離普查 ### 題目 問題描述: 村長現在想要統計村子裡面每條路的距離,每個人家到另外一個人家中間可能會有一 條路,村長想要知道這些路誰家到誰家較近,方便做一個緊急通訊錄,以防不時之需。 輸入說明 第一列的整數 ( 1 < n < 20 ) ,代表村中的道路共有幾條,其後有 n 列,每一列有 三個整數 x,y,d 代表的分別是村中某戶人家 x 到另一戶人家 y 的道路距離是 d ,其中距 離的值不超過 2000 ,且沒有數值相同的距離,各項資料用空白分開。 輸出說明: 印出排序後的道路距離由小到大 ,最後必須有換行字元。 ### 解題思路 - 開一個二維陣列`l`存`x`,`y`,`d`; - 用Bubble sort比路徑長短 ```cpp= #include <iostream> #include <utility> using namespace std; int main() { int a,b,c,t=0,i; string s; cin>>a; int l[a][3]; for(i=0;i<a;i++) { cin>>l[i][0]>>l[i][1]>>l[i][2]; } while(t>=0) { for(i=0;i<a-1;i++) { if(l[i][2]>l[i+1][2]) { //一次交換三個值 swap(l[i][0],l[i+1][0]); swap(l[i][1],l[i+1][1]); swap(l[i][2],l[i+1][2]); t++; } } t--; } for(i=0;i<a;i++) { cout<<l[i][0]<<' '<<l[i][1]<<' '<<l[i][2]<<endl; } } ``` ## 證書 ![image](https://hackmd.io/_uploads/HJ3aPvVwT.png)