华为机试---奖学金

题目描述

小v今年有n门课,每门都有考试,为了拿到奖学金,小v必须让自己的平均成绩至少为avg。每门课由平时成绩和考试成绩组成,满分为r。现在他知道每门课的平时成绩为a i ,若想让这门课的考试成绩多拿一分的话,小v要花b i 的时间复习,不复习的话当然就是0分。同时我们显然可以发现复习得再多也不会拿到超过满分的分数。为了拿到奖学金,小v至少要花多少时间复习。

输入描述:
第一行三个整数n,r,avg(n大于等于1小于等于1e5,r大于等于1小于等于1e9,avg大于等于1小于等于1e6),接下来n行,每行两个整数ai和bi,均小于等于1e6大于等于1


输出描述:
一行输出答案。

输入例子:
5 10 9
0 5
9 1
8 1
0 1
9 100

输出例子:

43

算法思想:
1.n门课平均成绩至少为avg,则最少分数=n*avg
2.要使花费复习时间最少只需满足平均成绩大于等于avg,不管单科成绩,
  则优先选择花费时间最少的课程开始复习,使其成为满分r

import java.util.Scanner; 
public class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
int n = scan.nextInt();//n门课
int r = scan.nextInt();//满分
int avg = scan.nextInt();//平均成绩
int[] A = new int[n];
int[] B = new int[n];
for(int i = 0 ; i < n ; i++){
A[i] = scan.nextInt();//每门课的平时成绩ai
B[i] = scan.nextInt();//花费bi时间复习多拿一分
}
System.out.println(spendTime(n , r , avg , A , B));
}
scan.close();
    }
private static long spendTime(int n, int r, int avg, int[] A , int[] B){
long minSpendTime = 0;//最少花费的时间,有可能超出int范围
int needScore = n * avg;//还需要获得的分数
//计算减去平时分还需要的分数
for(int i = 0 ; i < n ; i++){
needScore -= A[i];
}
while(needScore > 0){
int min_spend = Integer.MAX_VALUE;//每次保存提高相同分数需要的最小花费时间
int min_index = 0;//课程的下标
for(int i = 0 ; i < n ; i++){
//寻找花费复习时间最少的科目,使其变成满分
if(B[i] < min_spend && A[i] < r){
min_spend = B[i];
min_index = i;
}
}
//如果通过增加某门课的分数可以满足needScore
if(needScore < r - A[min_index]){
minSpendTime += needScore * B[min_index];
needScore = 0;
}else{
//如果通过增加某门课的分数不能满足needScore,使这门课变成满分,更新needScore
minSpendTime += (r - A[min_index]) * B[min_index];
needScore -= r - A[min_index];
A[min_index] = r;
}
}
return minSpendTime;
}

}

你可能感兴趣的:(java,华为)