zoukankan      html  css  js  c++  java
  • 1654. Minimum Jumps to Reach Home

    问题:

    一个虫子在x坐标的0位置出发,

    求最少跳多少次能跳到x位置。

    跳动规则:

    • 不能跳到forbidden所示的位置
    • 每次可向前跳 a 个距离。
    • 每次可向后跳 b 个距离。不能连续向后跳两次。
    • 不能跳到<0的坐标位置。
    Example 1:
    Input: forbidden = [14,4,18,1,15], a = 3, b = 15, x = 9
    Output: 3
    Explanation: 3 jumps forward (0 -> 3 -> 6 -> 9) will get the bug home.
    
    Example 2:
    Input: forbidden = [8,3,16,6,12,20], a = 15, b = 13, x = 11
    Output: -1
    
    Example 3:
    Input: forbidden = [1,6,2,14,5,17,4], a = 16, b = 9, x = 7
    Output: 2
    Explanation: One jump forward (0 -> 16) then one jump backward (16 -> 7) will get the bug home.
    
    Constraints:
    1 <= forbidden.length <= 1000
    1 <= a, b, forbidden[i] <= 2000
    0 <= x <= 2000
    All the elements in forbidden are distinct.
    Position x is not forbidden.
    

      

    解法:BFS

    • 状态:
      • 当前位置pos,最后一次跳动类型:向前?向后?
      • visited,记录跳动到过的位置。
    • 选择:(next位置>=0)
      • 向前
      • 向后:上一次不能是向后

    ⚠️ 注意:

    • 本题没有限制跳动位置的上限,
      • 因此为了防止TLE错误,我们需要判断跳动上限。maxbound
      • 只有a<b的时候,才可以向回跳,也会出现先跳到超过x的位置,再往回跳的情况。
      • 这时候上限为,可能到达的位置 max(x,forbidden),再往后尝试 最大 a+b
      • 即: max(x,forbidden)+a+b。
    • 当a>b的时候,只可能往前跳,此时pos如果超出x,且当前跳法是向后跳,那么之后的跳动只能使得离x越来越远。这种情况就不能再继续尝试了。

    代码参考:

     1 class Solution {
     2 public:
     3     int minimumJumps(vector<int>& forbidden, int a, int b, int x) {
     4         //state: last try type:1:forward, 0:backward
     5         //       pos
     6         //if try_type == forward(1): next can try both forward(1) and backward(0)
     7         //if try_type == backward(0): next can try only forward(1)
     8         //if a-b>0 && cur_try=backward && next-x>0: continue;
     9         //if pos in forbidden continue;
    10         //if pos in visited continue;
    11         //if pos<0 || pos>2000 continue;
    12         int tryt[2] = {-b, a};
    13         unordered_set<int> visited(forbidden.begin(), forbidden.end());
    14         queue<pair<int, int>> q;
    15         q.push({0,0});//first try must be forward
    16         visited.insert(0);
    17         //get maxbound: only backward case(b>a)
    18         //max pos we can reach=max(x,forbidden), + try_forwardmax(a+b)
    19         int maxbound = x;
    20         for(int fbd:forbidden) maxbound = max(maxbound, fbd);
    21         maxbound = maxbound+a+b;
    22         int step = 0;
    23         while(!q.empty()) {
    24             int sz = q.size();
    25             for(int i=0; i<sz; i++) {
    26                 auto [pos, trytype] = q.front();
    27                 q.pop();
    28                 if(pos==x) return step;
    29                 for(int j=0; j<2; j++) {
    30                     if(trytype==0 && j==0) continue;
    31                     int next = pos+tryt[j];
    32                     if(a-b>0 && j==0 && next-x>0) continue;
    33                     if(next<0 || next>maxbound) continue;
    34                     if(visited.insert(next).second) {
    35                         q.push({next, j});
    36                     }
    37                 }
    38             }
    39             step++;
    40         }
    41         return -1;
    42     }
    43 };
  • 相关阅读:
    socket学习笔记——获取域名与IP(linux)
    socket学习笔记——实现收发文件(Windows)
    socket学习笔记——IO口的基本操作(读、写)
    Microsoft Visual C++ 2010(86) Redistributable不能安装完美解决
    AD转换精度的计算
    cuda编程基础
    CUDA中并行规约(Parallel Reduction)的优化
    Warp divergence
    提取图片中文字
    GPU基本概念详解
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14562564.html
Copyright © 2011-2022 走看看