描述
在程设班里,每个学生每分钟可以自己编写 a 行代码。现在班级里只有一位助教,他很厉害。助教每分钟可以额外帮助一个学生编写 b 行代码(也就是说,该学生每分钟可以编写 a+b 行代码),
但在同一时间内助教只能帮助一个学生。现在有 n 个学生,第 i 个学生需要编写的代码量为 wi 行,请你求出所有学生完成编写所有代码的最少时间(以一分钟为最小单位)。
输入
第一行三个整数,分别为 n, a, b。
接下来第 2 到第 n+1 行,第 i 行输入 wi。
1 ≤ wi, a, b, n ≤ 5 × 105
输出
一行,表示让所有学生完成编写代码的最少时间。
样例输入
3 2 1 1 2 3
样例输出
1
提示
样例解释
让助教帮助第三个学生即可在一分钟就完成。
另外,注意在计算过程中数据是否存在溢出的情况。
解题分析
这是一道很经典的贪心算法,我们首先去考虑如何达到助教帮学生写代码能够达到最快的速度。由于每分钟每个学生也会自己敲代码,所以实际上影响最终时间的是那个敲代码量最多的同学,所以只要助教每分钟去帮助敲代码量最多的同学即可(注意这个同学会发生改变,因为随着时间的进行,每分钟之后要敲最多代码的那个同学会发生改变)。
代码演示
#include <iostream>
#include <cstdio>
#include <queue>
#include <bitset>
#include <map>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <vector>
#include <sstream>
using namespace std;
int n,a,b;
int w[500005];
bool check(){
for(int i=1;i<=n;i++){
if(w[i]>0) return false;
}
return true;
}
void help(){
auto p=max_element(w+1,w+n+1);
*p-=b;
for(int i=1;i<=n;i++){
if(w[i]>0)
w[i]-=a;
}
}
int main(){
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++){
scanf("%d",&w[i]);
}
int k=0;
while(!check()){
k++;
help();
}
printf("%d\n",k);
return 0;
}