C語言中用佇列和搜尋解決"加1乘2平方問題"
阿新 • • 發佈:2019-02-09
描述
給定兩個正整數m、n,問只能做加1、乘2和平方這三種變化,從m變化到n最少需要幾次
輸入
輸入兩個10000以內的正整數m和n,且m小於n
輸出
輸出從m變化到n的最少次數
輸入樣例
1 16
輸出樣例
3
#include<iostream>
#include<stdio.h>
#include<queue>//用佇列宣告標頭檔案
using namespace std;
queue<int> q1;//宣告佇列
int m,n;
int used[10001]={0};//記錄哪個數已經搜尋過
int step[10001];//記錄計算了幾步
void init();
int bfs();
int moveto(int u,int dire);
int main()
{
int num;
scanf("%d%d",&m,&n);
init();//初始化函式
num=bfs();//搜尋並賦值
printf("%d\n",num);
return 0;
}
void init()
{
q1.push(m);//把起點加入佇列
used[m]=1;//標註起點是已到達過的結點
step[m]=0; //記錄起點是0步到達的結點
}
int bfs()
{
int u,v,i;
while(!q1.empty()) //當佇列不空時繼續
{
u=q1.front(); //隊首元素給U
q1.pop() ; //隊首元素出隊
for(i=0;i<3;i++) //0表示+1;1表示乘2;2表示平方
{
v=moveto(u,i); //u到達的第i個新狀態
if(v==n) //如果v是目標
{
return (step[u]+1); //返回到達目標的最小步數
}
if(v<=n&&used[v]==0) //如果未越界並且沒被用過(有進一步擴充套件價值);
{
q1.push(v);//v入隊
used[v]=1;//標記v是已到達過的節點
step[v]=step[u]+1; //記錄到達v的最小步數
}
}
}
return(-1);
}
int moveto(int u,int dire)//完成加一乘二平方運算的函式
{
if(dire==0)
{
return(u+1);
}
else if(dire==1)
{
return(2*u);
}
else if(dire==2)
{
return(u*u);
}
}