---
# System prepended metadata

title: 東華大學資管系初階程式設計（進階題）112年考古
tags: [公開發佈, C++, 東華大學]

---

# 東華大學資管系初階程式設計（進階題）112年考古
## 相關資訊
課程代碼：IM__1120AA-初階程式設計

老師：劉英和教授

使用程式：C++

[初階考古](https://hackmd.io/@sumo0711/SyFipiOfA)
## 免責申明
:::danger
此文件僅為個人參考解答，並非標準答案。請僅供個人學習使用，切勿用於商業用途，如有侵權請寫信告知。
:::
## 生活費
### Description
小鳴剛上大學拿到人生第一份零用錢，他希望寫一支可以幫他計算每天預算的程式。
請你讓小鳴可以輸入他的生活費，
幫他除以剩餘的天數，算出他每天可以用多少（如果有小數則無條件捨棄）。
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
請問您有多少生活費：**10000**
還剩下幾天需要過：**30**
您一天可以使用333元
### Solution
```cpp=
#include <iostream>
using namespace std;

int main()
{
    int pocket_money, day; // 利用 int 型態無條件捨去小數點後面的數字
    cout << "請問您有多少生活費:";
    cin >> pocket_money;
    cout << "還剩下幾天需要過:";
    cin >> day;
    pocket_money = pocket_money / day;
    cout << "您一天可以使用" << pocket_money << "元";
    return 0;
}
```
## 時分秒
### Description
「再等我15分鐘！」小依邊化著妝說著。
「每次等妳出門都好久」小鳴無奈。
「那等我900秒好了。」小鈴改口。
「ok！」小鳴覺得秒比分快多了，立刻答應。
仔細思考後，他就開始後悔了。
小鳴每次都無法快速轉換秒數和小時、分、秒，請你寫一個程式幫他吧！
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
請輸入您要轉換的秒數：**4853**
轉換結果為：
1小時20分鐘53秒
### Solution
```cpp=
#include <iostream>
using namespace std;

int main()
{
    int s, m, h, number;
    cout << "請輸入你想轉換的秒數:";
    cin >> number;
    h = number / 3600;      // 一小時為3600秒
    number = number % 3600; // 將餘數帶回 number
    m = number / 60;        // 一分鐘為60秒
    s = number % 60;        // 餘數為秒
    cout << "轉換結果為:\n" << h << "小時" << m << "分鐘" << s << "秒";
    return 0;
}
```
## 轉換電腦進位
### Description
請編寫一個程式，接受使用者輸入一個十進位數字，然後將該數字轉換為二進位、八進位和十六進位的表示形式，並輸出結果。

提示：
可以使用適當的內建函數或自行編寫轉換函數來實現進制轉換。
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
請輸入一個十進位數字：**42**
轉換結果：
二進位表示：101010
八進位表示：52
十六進位表示：2A
### Solution
```ccp=
#include <iostream>
#include <bitset>  //bitset
#include <iomanip> //setiosflags(ios::uppercase)
using namespace std;

int main()
{
    int ten_number;
    cout << "請輸入一個十進位的數字:";
    cin >> ten_number;
    cout << "轉換結果:\n";
    bitset<100> b(ten_number);            // 把10進位ten_number放到bitset進行轉換
    string s = b.to_string();             // 轉換成string
    s.erase(0, s.find_first_not_of('0')); // 利用string函數去除前面的0
    cout << "二進位表示:" << s << endl;
    // bitset<6> b(ten_number);
    // cout << "二進位表示:" << b << endl; // 原本寫的
    cout << oct << "八進位表示:" << ten_number << endl;
    cout << setiosflags(ios::uppercase) << hex << "十六進位表示:" << ten_number; // setiosflags(ios::uppercase)將十六進位abc轉換成大寫ABC
    return 0;
}
```
## 字串
### Description
請使用四種不同的方法的其中一種來實現以下多行字串：
```
Hello, World!
This is a multiline string.
It contains:
    - Bulleted
        - Nested
            - Items
    - And some code:
        int x = 10;
        int y = 20;    int sum = x + y;
```
（四種方法分別為String Literals、Backslash Character和
Raw String Literals)
#### String Literals
\n = 換行
\t = tab

#### Backslash Character
\  = 接續上一行程式

#### Raw String Literals
R"(能打任何字排版字串)"

### Example
```
Hello, World!
This is a multiline string.
It contains:
    - Bulleted
        - Nested
            - Items
    - And some code:
        int x = 10;
        int y = 20;    int sum = x + y;
```
### Solution
```cpp=
#include <iostream>
#include <string>
using namespace std;

int main()
{
  cout << "Hello, World!\n\
This is a multiline string.\n\
It contains:\n\
\t- Bulleted\n\
\t\t- Nested\n\
\t\t\t- Items\n\
\t- And some code:\n\
\t\tint x = 10;\n\
\t\tint y = 20;    int sum = x + y;";
  return 0;
}
```
## 一元二次方程式
### Description
寫一個幫忙解一元二次方程式的程式
（輸出的數字只到小數點第二位，且希望輸入一元二次方程式的a,b和c係數時，僅用空格隔開。）
（使用三元運算符）
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
請輸入一元二次方程式的係數a,b,c:**1 5 6**
方程式有兩個實根：-2.00 & -3.00
### Solution
```cpp=
#include <iostream>
#include <iomanip>
#include <cmath> // 數學函式庫
using namespace std;
// 一般二元一次方程式: ax^2 + bx + c = 0
// 判别式的計算方式是: Δ = b^2 - 4ac
// 其中，Δ表示判别式(discriminant)，b是x的一次系數，a是x的二次系數，c是常數。
// 如果 Δ > 0，有兩個不相等的實根。
// 如果 Δ = 0，有兩個相等的實根。
// 如果 Δ < 0，沒有實根。
// 求解的公式 x = (-b ± √Δ) / (2a)

int main()
{
  double a, b, c, root1, root2, root3;
  cout << "請輸入一元二次方程式的係數a,b,c:";
  cin >> a >> b >> c;
  double discriminant = b * b - 4 * a * c;
  int roots = (discriminant > 0) ? 2 : (discriminant == 0) ? 1 : 0;
  // discriminant = b^2 - 4ac
  // discriminant>0 roots=2 , discriminant=0 roots=1 , discriminant<0 roots=0
  cout << "方程式";
  switch (roots)
  {
  case 2: // roots=2
    root1 = (-b + sqrt(discriminant)) / (2 * a); // x = (-b + √Δ) / (2a)
    root2 = (-b - sqrt(discriminant)) / (2 * a); // x = (-b - √Δ) / (2a)
    cout << "有兩個實根: " << fixed << setprecision(2) << root1 << " & " << root2;
    break;
  case 1: // roots=1
    root3 = -b / (2 * a);
    cout << "有一個實根: " << fixed << setprecision(2) << root3;
    break;
  default: // roots=0
    cout << "無實根";
    break;
  }
}
```
### Verify
請輸入一元二次方程式的係數a,b,c:**1 -6 9**
方程式有一個實根: 3.00

請輸入一元二次方程式的係數a,b,c:**1 2 3**
方程式無實根

## 三元運算符
### Description
寫一個可以判斷輸入的三個數字是否可以組成一個三角形
(使用三元運算符)

#### 三元運算符
if else 的另一種寫法
>(判斷式)？成立要做的事：否則做這個

### Example
參考執行畫面如下：（粗體字為使用者輸入的）
請輸入三個正整數: **3 4 5**
這三個數能組成一個三角形。
### Solution
```cpp=
#include <iostream>
using namespace std;

// 三角形不等式（Triangle Inequality）任意兩邊的總長度必須大於或等於第三邊的長度。
// 具體來說，對於一個三角形，假設三邊的長度分別為 a、b 和 c，則三角形不等式可以表達如下：
// a + b > c
// a + c > b
// b + c > a
// 如果這些不等式都成立，則這三個邊可以形成一個有效的三角形。
// 如果有任何一個不等式不成立，則無法構成三角形。

int main()
{
  int a, b, c;
  cout << "請輸入三個正整數: ";
  cin >> a >> b >> c;
  cout << ((a + b > c) && (a + c > b) && (b + c > a) ? "這三個數能組成一個三角形。" : "這三個數無法組成一個三角形。");
}
```
### Verify
請輸入三個正整數: **1 2 4**
這三個數無法能組成一個三角形。

## Try-Catch
### Description
請設計一個程式， 可以幫忙處理克拉瑪法則的計算，克拉瑪法則是一種用於解線性方程的方法。
（需包含try catch來保護程式碼）
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
請輸入第一個方程式的係數(a1,b1,c1): **2 3 2**
請輸入第二個方程式的係數(a2,b2,c2): **3 4 2**
x的值為: -2
y的值為: 2
### Solution
```cpp=
#include <iostream>
#include <stdexcept> // Try-catch
using namespace std;

// 克拉瑪公式
// 方程式一：a1X + b1Y = c1
// 方程式二：a2X + b2Y = c2
// Delta = (a1 * b2) - (a2 * b1)
// X = (c1 * b2) - (c2 * b1) / Delta
// Y = (c1 * a2) - (c2 * a1) / (a2 * b1) - (a1 * b2)
// 條件一：若 Delta 不等於 0，則方程有一組解 X Y
// 條件二：若 Delta = 0，但 X Y 至少有一個不為 0，方程式無解
// 條件三：若 Delta = X = Y = 0，方程式無限多解

int main()
{
  try
  {
    double a1, a2, b1, b2, c1, c2, x, y;
    cout << "請輸入第一個方程式的係數(a1,b1,c1): ";
    if (!(cin >> a1) || !(cin >> b1) || !(cin >> c1)) // 判斷使用者輸入是否為整數
      throw runtime_error("請輸入整數");
    cout << "請輸入第二個方程式的係數(a2,b2,c2): ";
    if (!(cin >> a2) || !(cin >> b2) || !(cin >> c2)) // 判斷使用者輸入是否為整數
      throw runtime_error("請輸入整數");
    x = (c1 * b2 - c2 * b1) / (a1 * b2 - a2 * b1);
    y = (c1 * a2 - c2 * a1) / (a2 * b1 - a1 * b2);
    if ((a1 * b2 - a2 * b1) == 0) // 判斷 Delta 是否為 0
    {
      if ((x < 0) || (x > 0) || (y < 0) || (y > 0)) // 判斷 X Y 至少有一個不為 0
        throw runtime_error("方程式無解");
      else
        throw runtime_error("方程式無限多組解"); // X = Y = 0
    }
    // 無錯誤印出 X Y 的值
    cout << "x的值為: " << x << endl
         << "y的值為: " << y << endl;
  }
  catch (const runtime_error &e) // e 為 runtime_error 的變數
  {
    cout << "錯誤: " << e.what() << endl; // 輸出錯誤訊息
  }
  return 0;
}
```
### Verify
請輸入第一個方程式的係數(a1,b1,c1): **q 1 3**
錯誤: 請輸入整數

請輸入第一個方程式的係數(a1,b1,c1): **6 4 -18**
請輸入第二個方程式的係數(a2,b2,c2): **3 2 -1**
錯誤: 方程式無解

請輸入第一個方程式的係數(a1,b1,c1): **0 0 0**
請輸入第二個方程式的係數(a2,b2,c2): **0 0 0**
錯誤: 方程式無限多組解

## 猜數字
### Description
電腦以亂數產生一小於100的正整數（num），使用者不斷猜測該數（guess），每次猜測時電腦會提示猜的太大或太小，直到猜到或者猜超過五次為止。
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
Your guess?
**50**
Too high!
Guess again!(remaining times: 5)
**25**
Too high!
Guess again!(remaining times: 4)
**12**
Too low!
Guess again!(remaining times: 3)
**18**
Too high!
Guess again!(remaining times: 2)
**15**
Too low!
Guess again!(remaining times: 1)
**17**
Too high!
Game over!
### Solution
```cpp=
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

int main()
{
    int num, Answer, guess_num = 6;
    srand(time(NULL));         // 取得時間序列
    Answer = rand() % 100 + 1; // 取亂數 1-100
    // rand() 生成一個隨機整數。
    // %100 確保結果在0到99的範圍內。
    // +1 然後將範圍移動到1到100。
    cout << "Your guess?\n";
    while (guess_num > 0) // 6 次猜數字的機會
    {
        cin >> num;
        if (num == Answer)
        {
            cout << "Bingo!";
            break; // 直到使用者猜到答案 跳出 while
        }
        else
            cout << ((num > Answer) ? "Too high!\n" : "Too low!\n");
        // 如果使用者輸入大於 Answer 輸出 Too high! 否則輸出 Too low!
        guess_num -= 1;
        if (guess_num == 0)
            continue; // 如果 guess_num = 0 跳過這次迴圈
        cout << "Guess again!(remaining times: " << guess_num << ")\n";
    }
    if (guess_num == 0) // 如果猜滿五次還沒猜出
        cout << "Game over!\n";
    return 0;
}
```
## 消失的等差數列
### Description
你穿越成為一名天才偵探，遇到一個極具挑戰性的任務。在古老的地圖上，標記了兩串有規律的數字（等差級數），代表寶藏的座標。這兩串數字是經過精心安排的，但其中有兩個數字（以*來表示）被小偷偷走，使得你無法直接找到寶藏的位置。然而，你聰明的頭腦讓你想到可以設計一個程式，透過找出這兩個缺失的數字，來找到小偷藏寶藏的位置。給定兩串整數陣列A和B，假設它們都有相同的長度N，且內容都是1到N的整數，代表寶藏的座標。請你設計一個程式，找出在陣列A和陣列B中缺失的兩個數字。這兩個缺失的數字就是小偷所偷走的座標，將它們輸出後，你將能找到寶藏的位置，並成功解開這個謎題。
〈提示：用等差級數的公式解〉
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
Please enter the array length:
N=**10**
1 6 11 16 21 26 31 36 * 46 
1 9 17 25 33 41 49 57 65 * 
A[] common difference = 5
B[] common difference = 8
The disappearing array is:
A[8]=41 B[9]=73
### Solution
```cpp=
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

int N, D_A, D_B; // 數列長度 AB數列公差

void Random(int &RemoveA_par, int &RemoveB_par, int &D_A_par, int &D_B_par);
// 隨機取得要刪除陣列的數字 與 AB公差的值

void Initialize(int Initialize_A_par[], int Initialize_B_par[]);
// 初始化AB陣列

void Sum_before(int &Total_A_Sum_par, int &Total_B_Sum_par);
// 計算陣列和

int Sum_after(int Sum_par[]);
// 把刪除陣列後的數值加起來

int main()
{
    cout << "Please enter the array length:\nN=";
    cin >> N; // 輸入陣列長度
    int A[N], B[N], RemoveA, RemoveB, MissA, MissB, Total_A_Sum, Total_B_Sum;
    Random(RemoveA, RemoveB, D_A, D_B);   // 取得要刪除的陣列數字 與 AB公差的值
    Initialize(A, B);                     // 初始化陣列
    Sum_before(Total_A_Sum, Total_B_Sum); // 等差級數公式解
    A[RemoveA] = 0;                       // 刪除陣列的值
    B[RemoveB] = 0;
    MissA = Total_A_Sum - Sum_after(A); // 將原本的總和 - 刪除後的陣列總和 = 少掉的數字
    MissB = Total_B_Sum - Sum_after(B);
    cout << "A[] common difference = " << D_A << endl // 印出公差
         << "B[] common difference = " << D_B << endl;
    cout << "The disappearing array is:\nA[" << RemoveA << "]=" << MissA << "\tB[" << RemoveB << "]=" << MissB;
    return 0;
}

void Random(int &RemoveA_par, int &RemoveB_par, int &D_A_par, int &D_B_par)
{
    srand(time(NULL));        // 取得時間序列
    RemoveA_par = rand() % N; // 取得陣列要刪除的數字
    RemoveB_par = rand() % N;
    D_A_par = rand() % 10 + 1; // 取得陣列差的數字 取 1-10
    D_B_par = rand() % 10 + 1;
}

void Initialize(int Initialize_A_par[], int Initialize_B_par[])
{
    // G 為暫存值的變數 每增加一圈用複利的觀念
    for (int i = 0, G = 0; i < N; i++, G += D_A) // 賦予陣列數值
        Initialize_A_par[i] = G + 1;             // 從 1 開始賦予
    for (int i = 0, G = 0; i < N; i++, G += D_B)
        Initialize_B_par[i] = G + 1;
}

void Sum_before(int &Total_A_Sum_par, int &Total_B_Sum_par)
{
    Total_A_Sum_par = N * (2 + (N - 1) * D_A) / 2; // 等差級數公式解
    Total_B_Sum_par = N * (2 + (N - 1) * D_B) / 2;
}

int Sum_after(int Sum_par[])
{
    int sum = 0;
    for (int i = 0; i < N; i++)
    {
        if (Sum_par[i] == 0) // 如果碰到被移除的數字 就印出 * 顯示
            cout << '*' << " ";
        else
            cout << Sum_par[i] << " ";
        sum += Sum_par[i]; // 把所有陣列數值相加
    }
    cout << endl;
    return sum;
}
```
## 計算機
### Description
請設計一個簡易的計算機程式，該程式能夠讓使用者選擇四種基本的算術運算：加法、減法、乘法和除法。程式將要求使用者輸入兩個整數數字，然後根據使用者選擇的運算符號執行相應的計算。如果選擇的是除法，並且第二個數字為零，則程式會輸出「Cannot divide by zero！」的錯誤訊息。
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
Select +, -, * and / :
**+**
Enter two integers:
**2**
**4**
6
### Solution
```cpp=
#include <iostream>
using namespace std;

void Input(int &num1, int &num2);

int main()
{
    try
    {
        int num1, num2;
        char choose;
        cout << "Select +, -, * and / :\n";
        cin >> choose;
        if (choose == '+')
        {
            Input(num1, num2);
            cout << num1 + num2;
        }
        else if (choose == '-')
        {
            Input(num1, num2);
            cout << num1 - num2;
        }
        else if (choose == '*')
        {
            Input(num1, num2);
            cout << num1 * num2;
        }
        else if (choose == '/')
        {
            Input(num1, num2);
            if (num2 == 0)
                throw runtime_error("Cannot divide by zero!");
            cout << num1 / num2;
        }
        else
            throw runtime_error("Undefined Input");
    }
    catch (const runtime_error &e) // e 為 runtime_error 的變數
    {
        cout << "Error: " << e.what() << endl; // 輸出錯誤訊息
    }
    return 0;
}

void Input(int &num1, int &num2)
{
    cout << "Enter two integers:\n";
    cin >> num1 >> num2;
}
```
### Verify
Select +, -, * and / :
**/**
Enter two integers:
**9**
**0**
Error: Cannot divide by zero!

Select +, -, * and / :
**a**
Error: Undefined Input

## 質數
### Description
設計一個程式，讓使用者輸入一個正整數，列出所有小於它的質數並相加，輸出於螢幕。
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
Please enter a positive integer:
**20**
The prime number is:
2 3 5 7 11 13 17 19 
The sum is: 77
### Solution
```cpp=
#include <iostream>

using namespace std;

int main()
{
    int prime, num, sum = 0;
    cout << "Please enter a positive integer:\n";
    cin >> num;
    cout << "The prime number is:\n";
    for (int i = 2; i <= num; i++)
    {
        prime = 1; // 讓prime在 j 迴圈完之後又回到1
        for (int j = 2; j <= (i / 2); j++)
        {
            if (i % j == 0)
                prime = 0;
        }
        if (prime == 1)
        {
            cout << i << " ";
            sum += i;
        }
    }
    cout << endl << "The sum is: " << sum;
    return 0;
}
```
## 費氏數列
### Description
fib 費式數列
（請用RecursiveFunction撰寫）
### Example
參考執行畫面如下：（粗體字為使用者輸入的）
Please enter the Fibonacci sequence to be calculated:
**10**
The value of Fibonacci sequence is:
55
### Solution
```cpp=
#include <iostream>
using namespace std;
// 費氏數列
// 公式 F(0)=0, F(1)=1, F(n)=F(n−1)+F(n−2)

int fib(int n);

int main()
{
    int n;
    cout << "Please enter the Fibonacci sequence to be calculated:\n";
    cin >> n;
    cout << "The value of Fibonacci sequence is:\n" << fib(n);
    return 0;
}

int fib(int n)
{
    return (n == 0 || n == 1) ? n : (fib(n - 1) + fib(n - 2));
    // n 為 0 或 1 時，直接返回 n，作為遞迴的終止條件。
}
```
## 排列組合
### Description
勇敢的冒險家在神秘森林尋找魔法寶藏。魔法石上有五個字母：“a”、“b”、“c”、“d”和“e"。解開所有字母的全部排列，就能啟動魔法力量。請你撰寫一支程式幫助冒險家。
（請用Recursive Function撰寫）
### Example
a b c d e 
a b c e d 
a b d c e 
a b d e c 
a b e d c 
a b e c d 
a c b d e 
a c b e d 
a c d b e 
a c d e b 
a c e d b 
a c e b d 
a d c b e 
a d c e b 
a d b c e 
a d b e c 
a d e b c 
a d e c b 
a e c d b 
a e c b d 
a e d c b 
a e d b c 
a e b d c 
a e b c d 
b a c d e 
b a c e d 
b a d c e 
b a d e c 
b a e d c 
b a e c d 
b c a d e 
b c a e d 
b c d a e 
b c d e a 
b c e d a 
b c e a d 
b d c a e 
b d c e a 
b d a c e 
b d a e c 
b d e a c 
b d e c a 
b e c d a 
b e c a d 
b e d c a 
b e d a c 
b e a d c 
b e a c d 
c b a d e 
c b a e d 
c b d a e 
c b d e a 
c b e d a 
c b e a d 
c a b d e 
c a b e d 
c a d b e 
c a d e b 
c a e d b 
c a e b d 
c d a b e 
c d a e b 
c d b a e 
c d b e a 
c d e b a 
c d e a b 
c e a d b 
c e a b d 
c e d a b 
c e d b a 
c e b d a 
c e b a d 
d b c a e 
d b c e a 
d b a c e 
d b a e c 
d b e a c 
d b e c a 
d c b a e 
d c b e a 
d c a b e 
d c a e b 
d c e a b 
d c e b a 
d a c b e 
d a c e b 
d a b c e 
d a b e c 
d a e b c 
d a e c b 
d e c a b 
d e c b a 
d e a c b 
d e a b c 
d e b a c 
d e b c a 
e b c d a 
e b c a d 
e b d c a 
e b d a c 
e b a d c 
e b a c d 
e c b d a 
e c b a d 
e c d b a 
e c d a b 
e c a d b 
e c a b d 
e d c b a 
e d c a b 
e d b c a 
e d b a c 
e d a b c 
e d a c b 
e a c d b 
e a c b d 
e a d c b 
e a d b c 
e a b d c 
e a b c d 
### Solution
```cpp=
#include <iostream>
using namespace std;

void swap(char &a, char &b);
void undo(char arr[], int start, int end);

int main()
{
    char abcde[5] = {'a', 'b', 'c', 'd', 'e'};
    undo(abcde, 0, 4);
    return 0;
}

// 交換兩個字
void swap(char &a, char &b)
{
    char temp = a;
    a = b;
    b = temp;
}

void undo(char arr[], int start, int end)
{
    // 如果已經處理到最後一個元素，輸出排列
    if (start == end)
    {
        for (int i = 0; i <= end; i++)
        {
            cout << arr[i] << " ";
        }
        cout << endl;
    }
    else
    {
        // 初始 start=0 end=4 逐一進行交換
        for (int i = start; i <= end; i++)
        {
            // 交換位置
            swap(arr[start], arr[i]);
            // 遞迴處理下一層
            undo(arr, start + 1, end);
            // 恢復原始順序，準備下一次交換
            swap(arr[start], arr[i]);
        }
    }
}
```