#I. 哆啦A梦的时光机(bfs经典习题)

文章描述了一个关于大雄和他的伙伴们使用故障时光机进行时空穿越的问题,需要找到从出发点S到目标点T,再返回S的最少操作次数。这个问题可以通过广度优先搜索(BFS)策略来解决,考虑时光机可以将时间点向前后移动一位或两倍,以及在偶数时刻减半。文章提供了代码示例来实现这个算法,主要涉及数据结构和算法的知识。
摘要由CSDN通过智能技术生成

题目

说明

有一天,大雄和他的伙伴们想穿越时空进行探险,可是时光机却出了一点故障,只能进行有限的时空穿越操作。大雄他们需要从现在出发,到达一个目标时间点进行探险,结束后再返回到现在,他们希望尽可能减少时光机的操作次数,你能帮助他们吗?

假设大雄和他的伙伴们出发的时间点(现在)为 S(0 < S < 1,000,000),希望到达的时间点(目标)为 T(0 < T < 1,000,000),已知时光机可以进行如下的时空穿越操作(X 为正整数):

可以从任意时刻X穿越到 X+1 或者 X-1 时刻

可以从任意时刻X穿越到 X * 2 时刻

当 X 为偶数时,可以从 X 时刻穿越到 X/2 时刻

请问,大雄和他的伙伴们从 S 时刻出发,先到达 T 时刻,再回到 S 时刻最少需要多少次时空穿越操作?

输入格式

输入的第一个数是一个正整数 N,表示测试数据一共有 N 组(0 < N < 20)。之后有 N 行,每一行包含两个正整数 S 和 T,表示出发和到达时间点。

保证 S != T

输出格式

输出包括N行,每一行一个正整数,表示每组测试数据对应的最少时光机操作次数。

样例

输入数据 1

2

5 17

4 8

输出数据 1

8

2

提示

对于 S=5,T=17:

操作如下:5->4->8->16->17->16->8->4->5

对于 S=4,T=8:操作如下:4->8->4


思路

建议先做信奥一本通1253抓住那头牛

典型的数轴bfs问题

大雄和他的伙伴们可以从x 走到x ± 12xx/2,请问农夫大雄和他的伙伴们最少移动多少次就能到达t时刻

深搜很有可能会找不到答案。而且不一定搜到底,所以就想到广搜,求最少步数

把当前能到达位置加入队列,对于每个位置按次序往四个方向加入队列,然后用一个vis判断是否走过,当走到目标点时,输出步数

注意:在这里因为是往返2次,所以要bfs2次,一次是bfs(n,k) ,一次是bfs(k,n)

ps:


代码

#include <bits/stdc++.h>
using namespace std;
int vis[1000010],dx[5];
int n,k;
queue <int> q;
int bfs(int x,int k)
{
  while(!q.empty()) q.pop();
  memset(vis,0,sizeof(vis));
  vis[x] = 1;
  q.push(x);
  while(!q.empty())
  {
    int t = q.front();
    if(t == k) return vis[t];
    dx[0] = t + 1;
    dx[1] = t - 1;
    dx[2] = t * 2;
    int p = 3;
    if(t % 2 == 0) dx[3] = t / 2,p++;
    for(int i = 0; i < p; i++)
    {
      if(dx[i] <= 1000000 && dx[i] >= 0 && vis[dx[i]] == 0)
      {
        q.push(dx[i]);
        vis[dx[i]] = vis[t] + 1;
      }
    }
    q.pop();
  }
}
int main()
{
  int t;
  cin>>t;
  while(t--)
  {
    cin>>n>>k;
    cout<<(bfs(n,k) - 1) + (bfs(k,n) - 1)<<'\n';
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值