解题思路

这是一个贪心算法问题。需要计算最少的复习时间来达到平均分要求。应该优先提高单位时间收益最大的课程分数。

关键点:

  1. 计算需要提高的总分数
  2. 按单位时间收益排序
  3. 考虑满分限制
  4. 贪心选择最优方案

算法步骤:

  1. 计算目标总分
  2. 按单位时间收益排序
  3. 贪心选择提分方案
  4. 累计所需时间

代码

#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

算法及复杂度

  • 算法:贪心算法
  • 时间复杂度:,主要是排序的时间
  • 空间复杂度:,不考虑输入数组