返回列表 發帖

資料結構 101 總分計算(易)

TQC+ 程式設計:資料結構 101 總分計算
1. 題目說明:
請依下列題意進行作答,使輸出值符合題意要求。

2. 設計說明:
請協助國小的班導師,設計一個程式,讓導師依次輸入學生的姓名、國文、英文和數學成績後,計算每位學生的成績總分與平均,並根據成績總分「由高至低」輸出結果。

3. 輸入輸出:
輸入說明
每一列依序輸入學生的姓名、國文、英文和數學成績,所有資料皆以半形空白間隔,直到該列輸入「END」表示結束。

註:姓名格式為英文字串(長度不超過20個字元);成績格式為 0 或正整數。

輸出說明
根據成績總分「由高至低」,依序輸出學生的姓名、國文成績、英文成績、數學成績、成績總分與平均(平均值請四捨五入至小數點後第二位),所有資料皆以半形空白間隔。

若成績總分相同,則依照資料輸入的先後順序輸出,即先輸入者先輸出。

範例輸入1
James 80 90 70
John 60 75 80
Carol 90 80 65
END
範例輸出1
James 80 90 70 240 80.00
Carol 90 80 65 235 78.33
John 60 75 80 215 71.67
範例輸入2
Robert 74 90 70
Michael 60 75 80
Linda 90 80 65
Barbara 75 85 60
William 45 90 90
END
範例輸出2
Linda 90 80 65 235 78.33
Robert 74 90 70 234 78.00
William 45 90 90 225 75.00
Barbara 75 85 60 220 73.33
Michael 60 75 80 215 71.67
May

回復 1# may
  1. //#include <iostream>
  2. //#include <vector>
  3. //#include <string>
  4. //#include <sstream>
  5. //#include <iomanip>
  6. //#include <algorithm>
  7. #include <bits/stdc++.h>

  8. using namespace std;

  9. // 定義學生結構體
  10. struct Student {
  11.     string name;
  12.     int chinese;
  13.     int english;
  14.     int math;
  15.     int total;
  16.     double average;
  17. };

  18. int main() {
  19.     vector<Student> students;
  20.     string input;
  21.    
  22.     while (getline(cin, input)) {
  23.         if (input == "END") break;
  24.         
  25.         stringstream ss(input);//透過 stringstream 解析輸入字串,
  26.         Student student;//存入 Student 結構體。
  27.         ss >> student.name >> student.chinese >> student.english >> student.math;
  28.         
  29.         // 計算總分與平均
  30.         student.total = student.chinese + student.english + student.math;
  31.         student.average = student.total / 3.0;
  32.         
  33.         students.push_back(student);//把單筆student資料放進vector陣列students裡
  34.     }
  35.    
  36.     // 排序:依據總分由高到低,若總分相同則保持原輸入順序
  37.     stable_sort(students.begin(), students.end(), [](const Student &a, const Student &b) {
  38.         return a.total > b.total;
  39.     });
  40.    
  41.     // 輸出結果
  42.     for (const auto &student : students) {//從vector中逐一用「引用」方式存取 students 裡的元素,並設為常數不會被修改。
  43.         cout << student.name << " "
  44.              << student.chinese << " "
  45.              << student.english << " "
  46.              << student.math << " "
  47.              << student.total << " "
  48.              << fixed << setprecision(2) << student.average << endl;//平均值四捨五入至小數點後第二位
  49.     }
  50.    
  51.     return 0;
  52. }
複製代碼
------------------------------------------
程式說明
學生資料結構(struct Student):

包含姓名 (name)、國文 (chinese)、英文 (english)、數學 (math) 成績。
計算出的成績總分 (total) 和平均 (average)。

讀取輸入
使用 getline(cin, input) 讀取每一行輸入,直到遇到 "END" 停止。
透過 stringstream 解析輸入字串,存入 Student 結構體。

計算總分與平均
total = chinese + english + math
average = total / 3.0(確保浮點數運算)

排序
使用 stable_sort(),確保相同總分的學生保持原輸入順序。
排序條件:總分 total 由高到低排序。

輸出格式
使用 fixed << setprecision(2) 讓平均值四捨五入到小數點後兩位。
確保輸出格式符合題目要求。
-----------------------------------------------------------------
測資:
測資 00
輸入0
Alice 85 90 80
Bob 70 75 85
Charlie 95 88 92
David 60 65 70
Eve 88 90 85
END
預期輸出0
Charlie 95 88 92 275 91.67
Eve 88 90 85 263 87.67
Alice 85 90 80 255 85.00
Bob 70 75 85 230 76.67
David 60 65 70 195 65.00

測資 01
輸入
Frank 100 100 100
Grace 99 98 97
Hank 85 88 90
Ivy 95 96 94
Jack 89 87 85
END
預期輸出
Frank 100 100 100 300 100.00
Ivy 95 96 94 285 95.00
Grace 99 98 97 294 98.00
Hank 85 88 90 263 87.67
Jack 89 87 85 261 87.00

測資 02
輸入
Leo 50 55 60
Mia 70 75 80
Noah 80 85 90
Olivia 90 95 100
Paul 40 45 50
END
預期輸出
Olivia 90 95 100 285 95.00
Noah 80 85 90 255 85.00
Mia 70 75 80 225 75.00
Leo 50 55 60 165 55.00
Paul 40 45 50 135 45.00

測資 03
輸入
Queen 100 90 95
Ryan 88 85 83
Sophia 76 80 85
Tom 95 92 96
Uma 87 89 86
END
預期輸出
Tom 95 92 96 283 94.33
Queen 100 90 95 285 95.00
Ryan 88 85 83 256 85.33
Uma 87 89 86 262 87.33
Sophia 76 80 85 241 80.33

測資 04
輸入
Victor 67 73 78
Wendy 82 85 88
Xander 90 92 91
Yara 60 70 80
Zack 99 98 100
END
預期輸出
Zack 99 98 100 297 99.00
Xander 90 92 91 273 91.00
Wendy 82 85 88 255 85.00
Victor 67 73 78 218 72.67
Yara 60 70 80 210 70.00

這些測資涵蓋了:
一般情況(學生成績不同,依總分排序)
極端情況(滿分 100 vs. 低分 40)
相同總分時的順序測試(確保 stable_sort() 保持輸入順序)
May

TOP

stable_sort 是什麼?

stable_sort 是 C++ 標準函式庫(<algorithm>)提供的排序函式。
它與 sort() 類似,但 可以保證相同數值的元素維持原本的順序。
時間複雜度:O(N log N),但比 sort() 可能稍慢,因為它需要維持穩定性。
Lambda 表達式 [](const Student &a, const Student &b) { return a.total > b.total; }
這是一個比較函式,用來告訴 stable_sort() 如何比較兩個學生 (a 和 b)。

拆解說明
[](const Student &a, const Student &b) { return a.total > b.total; }
[] 代表Lambda 表達式的開頭。
(const Student &a, const Student &b) 代表兩個要比較的學生。
{ return a.total > b.total; }
如果 a.total 大於 b.total,則 a 會排在 b 前面(即「由高到低」排序)。
否則 b 會在 a 前面。
為什麼使用 stable_sort() 而不是 sort()?
題目要求 「當總分相同時,維持原輸入順序」。

sort() 不保證 相同數值的元素維持輸入順序。
stable_sort() 可以保證 相同總分的學生按照輸入順序排列。
範例
假設有以下學生資料:

vector<Student> students = {
    {"Alice", 80, 85, 90, 255, 85.0},
    {"Bob", 90, 80, 85, 255, 85.0},  // 總分與 Alice 相同
    {"Charlie", 70, 75, 80, 225, 75.0}
};

排序前:

Alice    255
Bob      255
Charlie  225

當我們使用 stable_sort() 排序:

stable_sort(students.begin(), students.end(), [](const Student &a, const Student &b) {
    return a.total > b.total;
});

排序後:
Alice     255    (因為 Alice 先輸入,維持順序)
Bob      255   (Bob 之後輸入)
Charlie  225
這樣就能 符合題目要求:

總分由高到低
相同總分時,維持原輸入順序
總結

stable_sort(students.begin(), students.end(), [](const Student &a, const Student &b) {
    return a.total > b.total;
});
這行程式碼的作用
讓學生依「總分由高到低」排序。
如果總分相同,則保持原輸入順序(因為 stable_sort 會維持相同數值的順序)。
確保符合題目要求!
May

TOP

返回列表