小 Q 擔任裁判,需對選手得分進行處理,去除最高最低分後求平均,或類似的「去極值統計」問題。核心是貪心策略 + 高效數據結構維護有序序列。
#include
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m; // n 選手, m 裁判
while (cin >> n >> m) {
vector> scores(n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int x; cin >> x;
scores[i].insert(x);
}
}
for (int i = 0; i < n; i++) {
auto& ms = scores[i];
// 去除最高最低
ms.erase(ms.begin()); // 最低
ms.erase(prev(ms.end())); // 最高
// 計算平均
long long sum = 0;
for (int v : ms) sum += v;
double avg = (double)sum / ms.size();
cout << fixed << setprecision(2) << avg << "\n";
}
}
return 0;
}
begin() 最小,prev(end()) 最大。erase(iterator) 只刪一個元素 (關鍵!erase(value) 會刪所有相等值)。long long 累加避免溢出,double 除法,setprecision(2) 保留兩位小數。while (cin >> n >> m) 讀到 EOF 結束。
// 若每個選手分數固定,預排序存 vector,前綴和 O(1) 區間求和
vector> a(n, vector(m));
for (auto& v : a) { sort(v.begin(), v.end()); }
vector> pref(n, vector(m+1));
for (int i=0;i
適合離線、只讀場景,比 multiset 快得多。
| 坑點 | 後果 | 修正 |
|---|---|---|
ms.erase(val) | 刪除所有等於 val 的元素 | 用 ms.erase(ms.find(val)) 或迭代器 |
| 整數除法 | 精度丟失 | 轉 double 再除 |
| m=2 時去極值後空集 | 除零崩潰 | 題目保證 m≥3 或特判 |
| 輸出格式 | 格式錯誤 WA | fixed << setprecision(2) 強制兩位小數 |
若分數流式到達,需動態維護去極值平均,可用雙堆 (大根堆存小半、小根堆存大半) + 延遲刪除 或平衡 BST (policy_based_data_structure) 實現 O(log m) 插入/刪除/查詢中位數/去極值和。