// LeetCode 1792: Maximum Average Pass Ratio // 難度: Medium // 日期: 2025-09-01 using System; using System.Collections.Generic; using System.Linq; public class Solution { public double MaxAverageRatio(int[][] classes, int extraStudents) { // use priority queue var pq = new PriorityQueue(); // 初始化:將所有班級加入優先佇列 for (int i = 0; i < classes.Length; i++) { int pass = classes[i][0]; int total = classes[i][1]; double gain = CalculateGain(pass, total); pq.Enqueue(new ClassInfo(pass, total), -gain); } for (int i = 0; i < extraStudents; i++) { var classInfo = pq.Dequeue(); classInfo.Pass++; classInfo.Total++; double newGain = CalculateGain(classInfo.Pass, classInfo.Total); pq.Enqueue(classInfo, -newGain); } double totalRatio = 0; while (pq.Count > 0) { var classInfo = pq.Dequeue(); totalRatio += (double)classInfo.Pass / classInfo.Total; } return totalRatio / classes.Length; } public double MaxAverageRatioByBruteForce(int[][] classes, int extraStudents) { var n = classes.Length; var pass = new int[n]; var total = new int[n]; for (var i = 0; i < n; i++) { pass[i] = classes[i][0]; total[i] = classes[i][1]; } for (int student = 0; student < extraStudents; student++) { int bestClass = -1; double maxInprovement = 0; for (int i = 0; i < n; i++) { double currentAvg = CalculateAvergaeRatio(pass, total); pass[i]++; total[i]++; double newAvg = CalculateAvergaeRatio(pass, total); double improvement = newAvg - currentAvg; pass[i]--; total[i]--; if (improvement > maxInprovement) { maxInprovement = improvement; bestClass = i; } } if (bestClass != -1) { pass[bestClass]++; total[bestClass]++; } } return CalculateAvergaeRatio(pass, total); } private double CalculateGain(int pass, int total) { // 計算提升率 return (double)(pass + 1) / (total + 1) - (double)pass / total; } private double CalculateAvergaeRatio(int[] pass, int[] total) { double sum = 0; for (var i = 0; i < pass.Length; i++) { sum += (double)pass[i] / total[i]; } return sum / pass.Length; } } public class ClassInfo { public int Pass { get; set; } public int Total { get; set; } public ClassInfo(int pass, int total) { Pass = pass; Total = total; } } // 測試程式 public class Program { public static void Main() { Solution solution = new Solution(); // TestCase TestCase1(solution); TestCase2(solution); } static void TestCase1(Solution solution) { // Input: int[][] classes = new int[][] { new int[] {1, 2}, new int[] {3, 5}, new int[] {2, 2} }; int extraStudents = 2; Console.WriteLine("Test 1: "); Console.WriteLine($"classes: [{string.Join("], [", classes.Select(c => string.Join(", ", c)))}]"); Console.WriteLine($"extraStudents: {extraStudents}"); // Expected: Console.WriteLine("Expect: "); Console.WriteLine($"output: 0.78333"); // Actual: Console.WriteLine("Actual: "); Console.WriteLine($"Brute Force: {solution.MaxAverageRatioByBruteForce(classes, extraStudents):F6}"); Console.WriteLine($"Priority Queue: {solution.MaxAverageRatio(classes, extraStudents):F6}"); } static void TestCase2(Solution solution) { // Input: int[][] classes = new int[][] { new int[] {2, 4}, new int[] {3, 9}, new int[] {4, 5}, new int[] {2, 10} }; int extraStudents = 4; Console.WriteLine("Test 2: "); Console.WriteLine($"classes: [{string.Join("], [", classes.Select(c => string.Join(", ", c)))}]"); Console.WriteLine($"extraStudents: {extraStudents}"); // Expected: Console.WriteLine("Expect: "); Console.WriteLine($"output: 0.53485"); // Actual: Console.WriteLine("Actual: "); Console.WriteLine($"Brute Force: {solution.MaxAverageRatioByBruteForce(classes, extraStudents):F6}"); Console.WriteLine($"Priority Queue: {solution.MaxAverageRatio(classes, extraStudents):F6}"); } }