# 🔔CPE必考49題
## 🦤 1. Vito's Family
* **題目** :
![image](https://hackmd.io/_uploads/HyfExa7GR.png)
* **題目翻譯**
* **題目描述 :**
世界知名黑幫 Vito Deadstone 即將搬到紐約。他在那裡有一個非常龐大的家庭,他們都住在拉馬菲亞大道上。由於他將經常拜訪所有的親戚,他正在尋找一個靠近他們的房子。Vito 想要將到所有親戚的總距離最小化,並且已經勒索了你來撰寫一個解決他問題的程式。
* **輸入 :**
輸入包含多個測試案例。第一行包含測試案例的數量。對於每個測試案例,你將會得到一個整數表示親戚的數量 r (0 < r < 500) 以及他們住的街道號碼 (也是整數) s1, s2, . . . , si, . . . , sr (0 < si < 30000)。請注意,有些親戚可能住在相同的街道號碼上。
* **輸出 :**
對於每個測試案例,你的程式必須輸出從最佳 Vito 的房子到每一個親戚的最小距離總和。兩個街道號碼 si 和 sj 之間的距離為 dij = |si − sj|。
* **程式碼**
```cpp=
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
// 關閉同步,提高輸入輸出效率
ios_base::sync_with_stdio(0);
// 解除 cin 和 cout 的綁定,進一步提高效率
cin.tie(0);
int n, m;
cin >> n; // 讀取測試案例的數量
while (n--) { // 遍歷每個測試案例
cin >> m; // 讀取親戚的數量
int arr[m]; // 宣告一個長度為 m 的整數陣列,存放親戚的街道號碼
for (int i = 0; i < m; i++) {
cin >> arr[i]; // 讀取每個親戚的街道號碼
}
sort(arr, arr + m); // 將親戚的街道號碼按照升序排列
// 找出中位數,這樣可以使得到每個親戚的距離總和最小
int mid = arr[m / 2];
int sum = 0; // 初始化距離總和
// 遍歷每個親戚的街道號碼,計算到中位數的距離並加總
for (int i = 0; i < m; i++) {
sum += abs(arr[i] - mid);
}
// 輸出距離總和
cout << sum << endl;
}
return 0;
}
```
## 🦤 2. Hashmat the brave warrior
* **題目**:
![image](https://hackmd.io/_uploads/rkk4tFNMA.png)
* **題目翻譯**
* **題目描述 :**
Hashmat是一名勇敢的戰士,他與一群年輕的士兵一起,從一個地方移動到另一個地方,與對手作戰。在戰鬥之前,他只計算一件事,即他的士兵數量與對手的士兵數量之間的差異。根據這個差異,他決定是否要進行戰鬥。Hashmat的士兵數量永遠不會超過對手的士兵數量。
* **輸入 :**
輸入包含每行的兩個數字。每行中的這兩個數字表示Hashmat軍隊和他的對手軍隊的士兵數量,或者相反。輸入的數字不大於2^32。輸入以“End of File”終止。
* **輸出 :**
對於每一行輸入,請打印出Hashmat軍隊和他的對手軍隊之間士兵數量的差異。每個輸出應該在單獨的一行中。
* **程式碼**
```cpp=
#include <iostream>
using namespace std;
int main() {
// 宣告變數a和b,用於儲存Hashmat軍隊和對手軍隊的士兵數量
long long a, b;
// 循環讀取輸入直到檔案結束
while (cin >> a >> b) {
// 輸出Hashmat軍隊和對手軍隊士兵數量之間的差值的絕對值
cout << abs(b - a) << endl;
}
return 0;
}
```
## 🦤 3. Primary Arithmetic
* **題目** :
![image](https://hackmd.io/_uploads/S1hlzoNz0.png)
* **題目翻譯**
* **題目描述 :**
兒童被教導從右至左逐位數將多位數相加。許多人發現“進位”操作 - 將一個1從一個數位位置進位到下一個以相加 - 是一個重大挑戰。你的任務是計算一組加法問題中的進位操作次數,以便教育工作者可以評估它們的難度。
* **輸入 :**
每行輸入包含兩個小於10位數的無符號整數。輸入的最後一行包含“0 0”。
* **輸出 :**
對於每行輸入,除了最後一行,您應該計算並打印出從將兩個數字相加所產生的進位操作的數量,格式如下所示:
* **程式碼**
```cpp=
#include<iostream>
using namespace std;
int main() {
int carry = 0; // 初始化進位
int ans = 0; // 初始化進位操作次數
int n, m; // 宣告變數n和m,用於存儲輸入的數字
while (true) { // 進入無限循環,直到遇到條件跳出
cin >> n >> m; // 讀取輸入的兩個數字
if (n == 0 && m == 0) // 如果兩個數字均為0,跳出循環
break;
carry = 0; // 初始化進位為0
ans = 0; // 初始化進位操作次數為0
while (n != 0 || m != 0) { // 進入兩數相加的迴圈
if (n % 10 + m % 10 + carry > 9) { // 如果兩個數字的個位相加加上進位大於9
carry = 1; // 設置進位為1
ans = ans + 1; // 進位操作次數加1
} else { // 否則
carry = 0; // 重置進位為0
}
n = n / 10; // 將n除以10取整,即刪除個位
m = m / 10; // 將m除以10取整,即刪除個位
}
// 根據進位操作次數輸出結果
if (ans == 0)
cout << "No carry operation." << endl;
if (ans == 1)
cout << "1 carry operation." << endl;
if (ans > 1)
cout << ans << " carry operations." << endl;
}
return 0;
}
```
## 🦤 4. 3n+1 problem
* **題目** :
![image](https://hackmd.io/_uploads/ByXMQaSf0.png)
![image](https://hackmd.io/_uploads/rJ1QQ6rzC.png)
* **題目翻譯**
* **題目描述 :**
![image](https://hackmd.io/_uploads/Sy1DHTSzR.png)
![image](https://hackmd.io/_uploads/S1A5SpBfA.png)
*
* **輸入 :**
輸入將包含一系列整數對 i 和 j,每行一對整數。所有整數都將小於10,000且大於0。
你應該處理所有整數對,對於每對整數,確定在 i 和 j 之間(包括 i 和 j)的所有整數中的最大循環長度。
你可以假設沒有操作會導致32位整數溢出。
* **輸出 :**
對於每對輸入整數 i 和 j,你應該輸出 i、j 和在 i 和 j 之間(包括 i 和 j)的所有整數的最大循環長度。這三個數字應該至少用一個空格分隔,並且所有三個數字都在一行上,對於每行輸入,輸出一行。整數 i 和 j 必須按照它們在輸入中出現的順序出現在輸出中,並且應該在最大循環長度之後(在同一行上)。
* **程式碼**
```cpp=
#include<iostream>
using namespace std;
// 定義函數 f,計算循環長度
int f(int k) {
int ans = 1;
while (k != 1) {
if (k % 2 == 0) {
k = k / 2;
} else {
k = k * 3 + 1;
}
ans++;
}
return ans;
}
int main() {
int i, j;
while (cin >> i >> j) {
cout << i << " " << j << " ";
int max = 0; // 初始化最大循環長度為0
// 確保i小於j,如果不是,交換它們的值
if (j < i) {
int temp = j;
j = i;
i = temp;
}
// 遍歷所有從i到j的數字,計算最大循環長度
for (int min = i; min <= j; min++) {
if (f(min) > max)
max = f(min);
}
cout << max << endl; // 輸出i、j和最大循環長度
}
return 0;
}
```
* **題目** :
## 🦤 5. You can say 11
![image](https://hackmd.io/_uploads/S1h4haHGR.png)
* **題目翻譯**
* **題目描述 :**
你的任務是,給定一個正數N,判斷它是否是11的倍數。
* **輸入 :**
輸入是一個文件,每行包含一個正數。 包含數字「0」的行是
輸入結束。 給定的數字最多可以包含 1000 位數字。
* **輸出 :**
程式的輸出應指示每個輸入數字是否為 11 的倍數
* **程式碼**
```cpp=
#include<iostream>
using namespace std;
int main() {
string n;
int n1, n2;
while (cin >> n) {
n1 = 0;
n2 = 0;
if ((n == "0") && (n.length() == 1)) { // 當輸入為0時跳出迴圈
break;
}
for (int i = 0; i < n.length(); i++) { // 遍歷輸入數字的每一位
if ((i + 1) % 2 == 0) { // 如果是偶數位
n1 += n[i] - '0'; // 將該位數字加入n1中
} else { // 如果是奇數位
n2 += n[i] - '0'; // 將該位數字加入n2中
}
}
if (abs(n2 - n1) % 11 == 0) // 如果n2和n1的差值能被11整除,則輸出是11的倍數
cout << n << " is a multiple of 11." << endl;
else // 否則輸出不是11的倍數
cout << n << " is not a multiple of 11." << endl;
}
return 0;
}
```
## 🦤 5.
* **題目翻譯**
* **題目描述 :**
* **輸入 :**
* **輸出 :**
* **程式碼**
```cpp=
```