There are n workers. You are given two integer arrays quality and wage where quality[i] is the quality of the ith worker and wage[i] is the minimum wage expectation for the ith worker.
We want to hire exactly k workers to form a paid group. To hire a group of k workers, we must pay them according to the following rules:
Every worker in the paid group should be paid in the ratio of their quality compared to other workers in the paid group.
Every worker in the paid group must be paid at least their minimum wage expectation.
Given the integer k, return the least amount of money needed to form a paid group satisfying the above conditions. Answers within 10-5 of the actual answer will be accepted.
Example 1:
Input: quality = [10,20,5], wage = [70,50,30], k = 2
Output: 105.00000
Explanation: We pay 70 to 0th worker and 35 to 2nd worker.
Example 2:
Input: quality = [3,1,10,10,1], wage = [4,8,2,2,7], k = 3
Output: 30.66667
Explanation: We pay 4 to 0th worker, 13.33333 to 2nd and 3rd workers separately.
Constraints:
- n == quality.length == wage.length
- 1 <= k <= n <= 104
- 1 <= quality[i], wage[i] <= 104
当 rust 遇到浮点数, 就是一切噩梦的开始
题目其实不难, 被周边问题搞了个半死。
我们定义 ratio = wage / quality, 它代表工所能接受的单位 quality 所付 wage 的下限, 我们将工人按 ratio 排序, 这样我们遍历工人的时候 ratio 是非严格递增的(可能存在 ratio 相等的情况), 因为 ratio 是个下限, 所以我们选中的工人一定是按照最后一个进来的工人的 ratio 来计算工资, 高于这个 ratio 我们赔钱, 低于这个 ratio 至少最后进来的那个工人不干。我们将选中的工人的 quality 相加然后乘以 ratio 就是我们实际要支付的 wage。到这里我们就可以把问题转化的更简单一点, 对于任何一个工人, 我们要找到在他之前遍历的 k-1 个 quality 最小的工人, 然后加上当前工人的 quality, 用这个加和乘以当前工人的 ratio 就是如果选中当前工人所要支付的最低 wage。从这些值中挑出最小的就是我们要的答案。
问题搞清楚了,但是其实这才完成了一半,因为我们最终要的答案是浮点数,浮点数不准这点大家都知道,但题目还偏偏要求我们对比浮点数。像 python 这种对数字运算天然友好的语言可能还好点, 但像 rust 这种我只能定义一个类型来表达分数,并定义其相关运算,整个过程中我们用该类型进行计算和对比,最后将其转化为浮点数输出答案。所以代码看着会比较冗长, 大家见谅
use std::{
collections::BinaryHeap, ops::Mul};
#[derive(Debug, Eq)]
struct Fraction(i64, i64);
impl Fraction {
fn new(numerator: i32, denominator: i32) -> Self {
let gcd = Solution::gcd(numerator as i64, denominator as i64);
Self(numerator as i64 / gcd, denominator as