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 };
原文地址:https://www.cnblogs.com/habibah-chang/p/14562564.html