解题思路
这是一个贪心算法问题。需要计算最少的复习时间来达到平均分要求。应该优先提高单位时间收益最大的课程分数。
关键点:
- 计算需要提高的总分数
- 按单位时间收益排序
- 考虑满分限制
- 贪心选择最优方案
算法步骤:
- 计算目标总分
- 按单位时间收益排序
- 贪心选择提分方案
- 累计所需时间
代码
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
long long solve(int n, int r, int avg, vector<pair<int, int>>& courses) {
// 计算目标总分
long long targetSum = (long long)avg * n;
long long currentSum = 0;
// 计算当前总分
for (auto& course : courses) {
currentSum += course.first;
}
// 如果当前分数已经达标
if (currentSum >= targetSum) {
return 0;
}
// 按单位时间收益排序
sort(courses.begin(), courses.end(),
[](const pair<int, int>& a, const pair<int, int>& b) {
return a.second < b.second;
});
long long needScore = targetSum - currentSum;
long long totalTime = 0;
// 贪心选择
for (auto& course : courses) {
int currentScore = course.first;
int timePerScore = course.second;
// 计算当前课程可以提高的分数
long long canImprove = r - currentScore;
long long improve = min(canImprove, needScore);
totalTime += improve * timePerScore;
needScore -= improve;
if (needScore <= 0) break;
}
return totalTime;
}
};
int main() {
int n, r, avg;
// 持续读取输入直到EOF
while (cin >> n >> r >> avg) {
vector<pair<int, int>> courses(n);
for (int i = 0; i < n; i++) {
cin >> courses[i].first >> courses[i].second;
}
Solution solution;
cout << solution.solve(n, r, avg, courses) << endl;
}
return 0;
}
import java.util.*;
public class Main {
static class Solution {
public long solve(int n, int r, int avg, int[][] courses) {
// 计算目标总分
long targetSum = (long)avg * n;
long currentSum = 0;
// 计算当前总分
for (int[] course : courses) {
currentSum += course[0];
}
// 如果当前分数已经达标
if (currentSum >= targetSum) {
return 0;
}
// 按单位时间收益排序
Arrays.sort(courses, (a, b) -> Integer.compare(a[1], b[1]));
long needScore = targetSum - currentSum;
long totalTime = 0;
// 贪心选择
for (int[] course : courses) {
int currentScore = course[0];
int timePerScore = course[1];
// 计算当前课程可以提高的分数
long canImprove = r - currentScore;
long improve = Math.min(canImprove, needScore);
totalTime += improve * timePerScore;
needScore -= improve;
if (needScore <= 0) break;
}
return totalTime;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 持续读取输入直到EOF
while (sc.hasNext()) {
int n = sc.nextInt();
int r = sc.nextInt();
int avg = sc.nextInt();
int[][] courses = new int[n][2];
for (int i = 0; i < n; i++) {
courses[i][0] = sc.nextInt(); // 平时成绩
courses[i][1] = sc.nextInt(); // 单位时间
}
Solution solution = new Solution();
System.out.println(solution.solve(n, r, avg, courses));
}
sc.close();
}
}
class Solution:
def solve(self, n, r, avg, courses):
# 计算目标总分
target_sum = avg * n
current_sum = sum(score for score, _ in courses)
# 如果当前分数已经达标
if current_sum >= target_sum:
return 0
# 按单位时间收益排序
courses.sort(key=lambda x: x[1])
need_score = target_sum - current_sum
total_time = 0
# 贪心选择
for score, time in courses:
# 计算当前课程可以提高的分数
can_improve = r - score
improve = min(can_improve, need_score)
total_time += improve * time
need_score -= improve
if need_score <= 0:
break
return total_time
# 持续读取输入直到EOF
while True:
try:
# 读取每组测试数据
n, r, avg = map(int, input().split())
courses = []
for _ in range(n):
a, b = map(int, input().split())
courses.append((a, b))
solution = Solution()
print(solution.solve(n, r, avg, courses))
except EOFError:
break
算法及复杂度
- 算法:贪心算法
- 时间复杂度:,主要是排序的时间
- 空间复杂度:,不考虑输入数组