先按照复习的“性价比”排序,花较少单位时间的课程排在前面;
再计算出差多少分能够合格;
不断寻找能够补的课程并迭代缩小差距直至为0
#include <algorithm> #include <iostream> #include <vector> using namespace std; int main() { int n, r, avg; while (cin >> n >> r >> avg) { vector<pair<long long, long long>> ab; // 记录每门课的平时成绩与时间的数对 long long ai, bi; for (int i = 0; i < n; i++) { cin >> ai >> bi; ab.emplace_back(ai, bi); } // 按照复习所需时间从小到大排序 sort(ab.begin(), ab.end(), [&](const auto & a, const auto & b) { return a.second < b.second; }); // 当前平时成绩的总和 long long currSum = 0; for (const auto & [a, b] : ab) { currSum += a; } // 还差多少分能合格 long long diffSum = avg * n - currSum; // 记录复习用时 long long time = 0; for (const auto & [a, b] : ab) { // 如果课程已满分,跳过 if (a == r) { continue; } // 如果已经合格,跳出 if (diffSum <= 0) { break; } // 如果还要补的分数大于等于当前课程能补的分数,则把当前课程补到满分 // 如果还要补的分数小于当前课程能补的分数,则补足及格分即可 if (diffSum >= r - a) { diffSum -= r - a; time += (r - a) * b; } else { time += diffSum * b; break; } } cout << time << endl; } return 0; }
时间复杂度:O(n),用于遍历数对
空间复杂度:O(n),用于存储数对