腾讯笔试4.4第四题充电问题优先队列加数学计算ac

输入:
输入t表示案例数
输入n,w分别表示手机数和充电器功率
接下来的n行输入 a[i] b[i]表示每一部手机初始电量,和每一秒消耗的电量
输出:用充电器给这些手机轮流充电(不计切换时间),最多可以撑多久。

样例:
1
3 5
3 6
2 5
1 6

有三部手机,充电功率为5,可以以时间为横轴,剩余电量为纵轴画出这样的图:

可以看到最快用完电的手机是(1,6),没有充电器的话,答案就是1/6
在有充电器的情况下,我们可以减小每条线的斜率(通过充电降低手机的掉电速度)
问题转变成了如何合理分配充电器的功率(之所以能分配功率是因为充电器可以反复横跳😁),让这些手机中最早用完电的时间尽可能晚一些。
先给最拉垮的1号手机分配点功率,让1号的耗尽时间与2号的耗尽时间同步(0.4s),再同时给1号2号分配功率,直到它们与3号手机同步..........
重复此过程直到我们把充电器的功率彻底用完,最后输出这个耗尽时间。
当然功率够的话可以把所有斜率拨正。这时就输出-1
最后附上当时ac的代码。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        for(int i = 0; i < T; i++) {
            int n = sc.nextInt();
            double w = sc.nextDouble();
            PriorityQueue<double[]> pq = new PriorityQueue<>((a, b) -> (int) (a[0] * b[1] - a[1] * b[0]));
            for(int j = 0; j < n; j++) {
                pq.offer(new double[]{sc.nextInt(), sc.nextInt()});
            }
            while(w > 0) {
                if(pq.size() == 1) {
                    double[] cur = pq.poll();
                    if(cur[1] <= w) {
                        System.out.println(-1);
                        w = 0;
                    } else {
                        System.out.println(cur[0]/(cur[1] - w));
                        w = 0;
                    }
                } else {
                    double[] cur = pq.poll();
                    double[] next = pq.peek();
                    double temp = (next[0] * cur[1] - cur[0] * next[1]) / next[0];
                    if(w  > temp) {
                        w -= temp;
                        pq.poll();
                        pq.offer(new double[]{cur[0] + next[0], cur[1] + next[1] - temp});
                    } else if(w <= temp) {
                        System.out.println(cur[0]/(cur[1] - w));
                        w = 0;
                    }
                }
            }
        }
    }
}


#笔试题目##腾讯#
全部评论
结合个人理解给代码加上注释😀。
3 回复 分享
发布于 2021-04-05 16:50
还差第5题“最小砝码数量”没搞定,请教下楼主有思路吗?
点赞 回复 分享
发布于 2021-04-05 21:01
另一方面关于楼主代码有一个不成熟的小建议就是在输出 -1之后,应该吧w置为0或者return,退出while循环,否则可能会因为重复进入else分支,出现空指针异常。
点赞 回复 分享
发布于 2021-04-05 16:54
PriorityQueue<double[]> pq = new PriorityQueue<>((a, b) -> (int) (a[0] * b[1] - a[1] * b[0])); 楼主,这一句没看懂😂,可以帮忙解释一下嘛
点赞 回复 分享
发布于 2021-04-05 13:42
楼主第三题怎么做的
点赞 回复 分享
发布于 2021-04-05 13:02
楼主太厉害了! temp这里我看了半天才明白,帮楼主解释一下 next[0]/next[1] = cur[0]/(cur[1] - tmp)    ---> double temp = ((next[0] * cur[1]) - cur[0] * next[1]) / next[0];
点赞 回复 分享
发布于 2021-04-05 11:06
楼主充电也需要时间,给一号充电的同时二号不是在耗电么,那为啥还是0.4秒
点赞 回复 分享
发布于 2021-04-05 10:57
这题直接二分答案为啥是90...
点赞 回复 分享
发布于 2021-04-05 10:02

相关推荐

不愿透露姓名的神秘牛友
07-11 11:16
点赞 评论 收藏
分享
06-12 16:23
已编辑
小米_软件开发(准入职员工)
点赞 评论 收藏
分享
07-07 12:47
门头沟学院 Java
码农索隆:竟然还真有卡体检报告的
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-10 11:55
点赞 评论 收藏
分享
评论
12
34
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务