Description
小 M 现在被困在了一个山洞里需要你去解救。
格式化的说,可以把距离看成一个数轴,你现在在位置 1,小 M 在位置𝑝。
每经过一秒你可以向前走一步或者向后走一步。
你也拥有超能力可以进行传送你可以传送到你当前位置 三倍的地方也就是说如果你在𝑥那么你可以传送到数轴3𝑥的 位置。
你也可以向后传送,如果你当前的位置为𝑥,那么你可以 传送到 𝑥/2 的位置,但是要保证当前𝑥是一个偶数。 请你用最短的时间解救小 M。
Input
一个整数𝑇 1 ≤ 𝑇 ≤ 100代表测试数据的数量。 每组测试数据包含一个整数𝑝 1 ≤ 𝑝 ≤ 100代表小 M 当 前的位置。
Output
对于每组测试数据输出一个整数,代表所需要的最少的秒数。
Sample Input
3 1 3 5Sample Output
0 1 3
第一眼看过去想要用到DFS,但又想了一下还是BFS比较合适。
写的时候还是在数据的条件判定上出现了不少问题,导致浪费了很多时间。
以下是AC代码
#include<bits/stdc++.h>
using namespace std;
int bfs(int m){
int a[1001]={0};
int b[1001]={0};//这里要定义一个比100大一些的数组,数轴的长度是要比100大的,并且在本题中小于一部分的数轴是没有意义的
queue<int>s;
int time2=0;
s.push(1);//这里图省事直接在dfs中定义变量,省去初始化的操作
while(!s.empty()){
int u=s.front();
s.pop();
if(u!=1)//这个if多余了
{
if(u%3==0&&a[u/3]!=0)
{
time2=a[u/3];
}
if(u+1<=1000&&a[u+1]!=0&&a[u+1]<time2)
time2=a[u+1];
if(u-1>=1&&a[u-1]!=0&&a[u-1]<time2)
time2=a[u-1];
if(u*2<=1000&&a[u*2]!=0&&a[u*2]<time2)
time2=a[u*2];
}//选出可以最快到达u点的时间
a[u]+=time2;//记录
if(u==m){
return a[u];//返回值
}
else{
if(u*3<=1000&&b[u*3]==0){
s.push(u*3);
b[u*3]=1;//标记点以保证每次的点不会重复
}
if(u%2==0&&b[u/2]==0){
s.push(u/2);
b[u/2]=1;
}
if(u+1<=1000&&b[u+1]==0){
s.push(u+1);
b[u+1]=1;
}
if(u-1>=1&&b[u-1]==0){
s.push(u-1);
b[u-1]=1;
}
b[u]=1;
a[u]++;//为u点的下一点加一
}
}
}
int main(){
int n;
cin>>n;
while(n--){
int m;
cin>>m;
int count=bfs(m);
cout<<count<<endl;
}
return 0;
}