这道题的网址
请速览一遍原题
当然,咱们来进行
题面关键信息提取
1.机器人从第1个格子出发;
2.设机器人目前所在格子的编号为x,则它能够跳到格子的编号可能是x,x+1或2x,也就是说,新跳到格子的编号,可能是比原来格子编号少1或多1,或是其2倍;
3.不允许跳出界,举个简单的例子,就拿题目中的这句话来说:
一眼看出,63+1=64,而64=2^6,所以直接1->2->4->8->16->32->64->63秒了,7步,可以吗?
显然不行。为什么?
一共63个格子,能走到第64个格子吗?当然不能。
所以这道题的思考,不能简单化处理。
4.注意取值范围。
那么接下来怎么办?
题面分析
一、知识点
从第1个格子出发到终点,机器人在每一个格子最多可能往3种方向行驶。但我要求用最少的部分,也就是找:最短路。敏感度一定要有,用到哪个知识点?
看,“标签”选项卡的显示,证明了咱们方向的正确。
回忆一下BFS的伪代码:(以下仅为示例,不代表解题代码)
将队列q初始化
起点s入队
标记s为已访问
while(队列q非空)
{
取出队首
将队首弹出队列
枚举队首的可达状态//此步仅为参考
其他操作
if(可达状态符合要求)
将该可达状态入队
}
二、答案记录
对于答案的记录,大家可能有很多种方法,大家可以把大家的方法公布出来,在这里,由于空间限制是128MB,而开一个int arr[1000086]只需约4MB,所以我使用的方法,还是开数组记录。
那咱们可以开始写了
一、先把这几句写好
#include<bits/stdc++.h>
using namespace std;
queue<int> q;
int arr[1000010];
int main()
{
memset(arr,-1,sizeof arr);
int n;
cin>>n;
q.push(1);
while(!q.empty())
{
int f=q.front();
q.pop();
//something else
}
return 0;
}
那咱们现在就要想一想,步骤是什么样的呢?
二、步骤梳理
1.设s=arr[d],则说明在第s步,可以走到第d格。但在解题开始,每个格都没有被走过,那应初始化为-1,表示暂未到达。(实际上0等值也可以,大家可以自己试一试)。实际将arr定义在堆空间(main()函数之外)即可;
2.arr[1]是起点,可以看做是第0步可以到达的状态,所以要保证arr[1]=0;
3.注意循环迭代中关键量的变化。
若arr[5]=6,那么arr[4],arr[6],arr[10]都可以确定了,他们就是6+1=7;
若arr[f]=m,则有arr[f-1]=arr[f+1]=arr[2*f]=m+1。
这步理清了。
而且知道arr[1]=0,这就把联系线理出来了。
又完成一部分:
#include<bits/stdc++.h>
using namespace std;
queue<int> q;
int arr[1000010];
int main()
{
memset(arr,-1,sizeof arr);
int n;
int m;
arr[1]=0;
cin>>n;
q.push(1);
while(!q.empty())
{
int f=q.front();
m=arr[f];//呼应前面咱们说的:若arr[f]=m,则有arr[f-1]=arr[f+1]=arr[2*f]=m+1。
q.pop();//一定要记得弹出队首
int b1=f-1,b2=f+1,b3=f*2;//枚举可达状态
//something else
}
cout<<arr[n]<<endl;
return 0;
}
那么在将可达状态重新入队并处理的时候,有哪些条件呢?
①这个可达状态在1~n的范围内,也就是说,没有跳出格子的范围;
②这个地方“没有踏足过”,在之前,建议大家arr初始化为-1,表示暂未到达;所以,需要保证arr[该可达格子]=-1;
上面的b1,b2,b3都是理想可达状态,他们都需要判断,看看是否符合这两个条件,所以大家知道,需要分支语句条件判断。(注:如果不写分支语句,直接将理想可达状态入队,可能会出现循环无法跳出的情况。)那么,符合这两个条件,怎么办呢?
①将该可达状态重新入队;
②在arr中标记,按照咱们前面的这句话,
“若arr[f]=m,则有arr[f-1]=arr[f+1]=arr[2*f]=m+1”,
他们应该全部被标记为m+1。
所以继续完成剩余部分:
if(b1>=1&&b1<=n&&arr[b1]==-1) q.push(b1),arr[b1]=m+1;
if(b2>=1&&b2<=n&&arr[b2]==-1) q.push(b2),arr[b2]=m+1;
if(b3>=1&&b3<=n&&arr[b3]==-1) q.push(b3),arr[b3]=m+1;
上完整代码
#include<bits/stdc++.h>
using namespace std;
queue<int> q;
int arr[1000010];
int main()
{
memset(arr,-1,sizeof arr);
int n;
int m;
arr[1]=0;
cin>>n;
q.push(1);
while(!q.empty())
{
int f=q.front();//取出队首
m=arr[f];
q.pop();//一定要记得弹出队首
int b1=f-1,b2=f+1,b3=f*2;//枚举可达状态
if(b1>=1&&b1<=n&&arr[b1]==-1) q.push(b1),arr[b1]=m+1;
if(b2>=1&&b2<=n&&arr[b2]==-1) q.push(b2),arr[b2]=m+1;
if(b3>=1&&b3<=n&&arr[b3]==-1) q.push(b3),arr[b3]=m+1;
//若arr[f]=m,则有arr[f-1]=arr[f+1]=arr[2*f]=m+1
}
cout<<arr[n]<<endl;
return 0;
}
标签:arr,洛谷,格子,B3626,int,入队,b1,&&,解析
From: https://blog.csdn.net/2402_82882092/article/details/140579189