蓝桥杯第199题 扫地机器人 暴力优化 二分法 简单题 C++

8 篇文章 0 订阅
6 篇文章 0 订阅

题目

扫地机器人 - 蓝桥云课 (lanqiao.cn)icon-default.png?t=N7T8https://www.lanqiao.cn/problems/199/learning/?page=1&first_category_id=1&name=%E6%89%AB%E5%9C%B0%E6%9C%BA%E5%99%A8%E4%BA%BA

思路和解题方法

  1. 首先,通过cin语句输入了终点位置n和障碍物数量k。
  2. 使用一个数组a来存储k个障碍物的位置。
  3. 对障碍物位置进行排序,以便后续的二分搜索。
  4. 然后,定义了一个函数check,用于检查是否能够在给定的时间内到达终点。该函数采用二分搜索的思想。
  5. check函数中,首先初始化当前位置为起点0。然后遍历每一个障碍物:
    • 如果当前位置小于障碍物位置,则需要额外花费时间走过去,时间花费为(a[i] - pos - 1) * 2
    • 若剩余时间不足以到达当前障碍物,则返回false,表示无法在给定时间内到达终点。
    • 否则,更新当前位置为走过障碍物后的位置,即pos = a[i] + t / 2
  6. 当所有障碍物都走过后,判断当前位置是否小于终点位置n,若小于则返回false,表示无法在给定时间内到达终点;否则返回true,表示可以在给定时间内到达终点。
  7. 主函数使用二分搜索来找到最短时间。初始化二分搜索的左边界l为0,右边界r为2 * n。
  8. 在while循环中,计算中间值mid,并调用check函数判断是否能在mid时间内到达终点。
    • 若可以,则更新答案ans为mid,并将右边界r缩小为mid-1,继续搜索更短的时间。
    • 若不可以,则将左边界l扩大为mid+1,继续搜索更长的时间。
  9. 最终输出答案ans,即为最短时间到达终点的结果。

复杂度

        时间复杂度:

                O(log N * K)

        时间复杂度为O(logN * K),其中N为终点位置,K为障碍物数量。主要时间消耗在二分搜索中。

        空间复杂度

                O(K)

        空间复杂度为O(K),其中K为障碍物数量,因为需要使用一个数组来存储障碍物的位置。

c++ 代码

#include<iostream>
#include<algorithm>
using namespace std;

int n, k, a[100005]; // 定义变量n(终点位置)、k(障碍物数量)、a数组存放k个障碍物的位置
int ans; // 存放最终答案

// 检查是否能够在给定的时间内到达终点
bool check(int time)
{
    int pos = 0; // 当前位置初始化为起点
    for(int i = 0; i < k; ++i) // 遍历每一个障碍物
    {
        int t = time; // t表示剩余时间
        if(pos < a[i]) // 如果当前位置小于障碍物位置
            t -= (a[i] - pos - 1) * 2; // 则需要额外花费时间走过去
        if(t < 0) // 如果剩余时间不足以到达当前障碍物
            return false; // 返回false,表示无法在给定时间内到达终点
        pos = a[i] + t / 2; // 更新当前位置为走过障碍物后的位置
    }
    if(pos < n) // 如果所有障碍物都走过后,仍未到达终点
        return false; // 返回false,表示无法在给定时间内到达终点
    return true; // 否则返回true,表示可以在给定时间内到达终点
}

int main()
{
    cin >> n >> k; // 输入终点位置n和障碍物数量k
    for(int i = 0; i < k; i++)
        cin >> a[i]; // 输入k个障碍物的位置
    sort(a, a + k); // 对障碍物位置进行排序
    int l = 0, r = 2 * n; // 初始化二分搜索的左右边界

    while(l <= r) // 二分搜索
    {
        int mid = l + (r - l) / 2; // 取中间值
        if(check(mid)) // 能够在mid时间内到达终点
            ans = mid, r = mid - 1; // 更新答案并缩小右边界
        else
            l = mid + 1; // 否则扩大左边界
    }

    cout << ans << endl; // 输出答案
    return 0;
}

未优化的代码 暴力 time从0~2*n

	for(int i = 0;i<=2*n;i++)
    {
        if(check(i)){
            ans = i;
            break;
        }
    }

时间对比

我的文档里面也有许多二分(双指针)题目,可供大家参考作答。

双指针_冷yan~的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/jgk666666/category_12470278.html

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值