#day6 力扣每日一题1870

题目1870.准时到达的列车最小时速. - 力扣(LeetCode)

给你一个浮点数 hour ,表示你到达办公室可用的总通勤时间。要到达办公室,你必须按给定次序乘坐 n 趟列车。另给你一个长度为 n 的整数数组 dist ,其中 dist[i] 表示第 i 趟列车的行驶距离(单位是千米)。

每趟列车均只能在整点发车,所以你可能需要在两趟列车之间等待一段时间。

  • 例如,第 1 趟列车需要 1.5 小时,那你必须再等待 0.5 小时,搭乘在第 2 小时发车的第 2 趟列车。

返回能满足你准时到达办公室所要求全部列车的 最小正整数 时速(单位:千米每小时),如果无法准时到达,则返回 -1 。

生成的测试用例保证答案不超过 107 ,且 hour 的 小数点后最多存在两位数字 。

示例 1:

输入:dist = [1,3,2], hour = 6
输出:1
解释:速度为 1 时:
- 第 1 趟列车运行需要 1/1 = 1 小时。
- 由于是在整数时间到达,可以立即换乘在第 1 小时发车的列车。第 2 趟列车运行需要 3/1 = 3 小时。
- 由于是在整数时间到达,可以立即换乘在第 4 小时发车的列车。第 3 趟列车运行需要 2/1 = 2 小时。
- 你将会恰好在第 6 小时到达。

提示:

  • n == dist.length
  • 1 <= n <= 105
  • 1 <= dist[i] <= 105
  • 1 <= hour <= 109
  • hours 中,小数点后最多存在两位数字

思路

1、设速度的上、下限,二分查找最小速度。

2、若hour<=n-1则直接返回-1。因为前n-1段路程最少都要向上取整为(n-1)*1,还有最后一段路程未计算。

3、时间计算:不是最后一段路程的时间都要用ceil()函数向上取整。最后一段路程不用向上取整,因为下一段路程不用从整数开始。

4、最大时速right边界的讨论(还不会思密达)

dist[i]最大为1e5,最小有效的时间hour是1.01,此时时速至少需要接近1e5

5、c++中两个整型数值相除得到的还是整型,这是整型精确计算所要求的。必须转换为浮点型再进行运算。如下述代码中totalTime += dist[n-1]/(double)speed;

代码

class Solution {
public:
    int n=0;    //dist容器的大小

    int minSpeedOnTime(vector<int>& dist, double hour) {
        n=dist.size();    

        //因为前n-1段路程最少都需要1小时,还有第n段路程
        if(hour<=n-1) return -1;

        //搜索的速度范围
        int left=1,right=1e7;
        int result = -1;

        while(left <= right){
            int mid = left + (right-left)/2;    //计算中间速度
            if(canReachOnTime(dist,hour,mid)){  //可以完成
                result=mid;
                right=mid-1;    //寻找更小的速度
            }else{
                left = mid+1;
            }
        }
        return result;
    }

    bool canReachOnTime(const vector<int>& dist, double hour, int speed){
        double totalTime=0;
        n=dist.size();
        for(int i=0;i<n-1;i++){
            totalTime+=ceil(dist[i]/(double)speed);
        }
        totalTime+=dist[n-1]/(double)speed;
        
        return totalTime<=hour; //是否能在指定时间完成路程
    }
};

知识补充

参考链接:C++基础——向上取整/向下取整_c++向上取整函数-CSDN博客

头文件#include <math.h>

或者 #include <cmath>

floor()不大于自变量的最大整数

ceil()不小于自变量的最小整数

round()四舍五入到最邻近的整数

fix()朝零方向取整,整数向下取,负数向上取。


错误思路

最大速度并不是max(dist[])

class Solution {
public:
    int minSpeedOnTime(vector<int>& dist, double hour) {
        //最大的速度是dist[]的max值。每段最快也要花一小时,因为要从整数出发
        int n =dist.size();
        int max_speed = *max_element(dist.begin(),dist.end());
        long double h=0;

        for(int i=0;i<n;i++){
            if(i!=n-1){
                h+=ceil(dist[i]/(double)max_speed);
            }else{
                h+=dist[i]/(double)max_speed;   //要转成浮点数类型
            }
        }

        if(h>hour) return -1;   //最大速度已经不能满足
        else{
            while(h<=hour){
                h=0;
                max_speed--;
                for(int i=0;i<n;i++){
                    if(i!=n-1){
                        h+=ceil(dist[i]/(double)max_speed);
                    }else{
                        h+=dist[i]/(double)max_speed;   //要转成浮点数类型
                    }
                }
            }
            max_speed+=1;
            return max_speed;
        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值