DESCRIPTION
没时间编故事了,直接做题吧!问题很简单,现在有两个数n和m,我们有三种操作-1,+1,*2。问:最少需要操作多少次能把n变成m。(0<=n,m<=1000000)
INPUT
输入数据有多组,每行输入两个整数n和m
OUTPUT
每行输出一个数字代表最少操作次数
SAMPLE INPUT
5 17
SAMPLE OUTPUT
4
还没怎么学习数据结构和C++的我,还是个菜鸟,还是师傅好~~给我发代码,让我自己琢磨,这个过程中,还是多多少少领悟到一些东西的,下面是题解及我学习过程中查阅的资料,希望对你有所帮助
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int MAX = 1000100;
int n, m;
int vis[MAX+10];
struct Step
{
int data;
int steps;
Step(int data,int s):data(data),steps(s){}//初始化结构体
};
int main()
{
while(scanf("%d%d",&n,&m) != EOF)//读取到文件末尾结束
{
queue<Step> q;//
memset(vis,0,sizeof(vis));//分配内存空间,初始化vis[],0表示未被访问
q.push(Step(n,0));//Step(n,0)入队
vis[n] = 1;//入队后表示1表示被访问过
while( !q.empty() )//判断队列是否为空
{
Step temp = q.front();//获取队列首元素
printf("%d %d\n",temp.data,temp.steps);//输出操作步骤
if(temp.data == m)
{
printf("%d\n",temp.steps);
break;
}
else
{
if(temp.data - 1 >= 0 && !vis[temp.data-1])
{
q.push(Step(temp.data-1,temp.steps+1));
vis[temp.data-1] = 1;//记忆化搜索
}
if(temp.data + 1 <= MAX && !vis[temp.data+1])
{
q.push(Step(temp.data+1,temp.steps+1));
vis[temp.data+1] = 1;
}
if(temp.data * 2 <= MAX && !vis[temp.data*2])
{
q.push(Step(temp.data*2,temp.steps+1));
vis[temp.data*2] = 1;
}
q.pop();//扫描过的元素出队
}
}
}
return 0;
}
附:
Step(int xx, int s):x(xx), steps(s){ }
是这个Step结构体的构造函数,C++中的结构体和C中不太一样,已经可以像和C++中的类一样写入函数了,
函数括号后面的是初始化列表,上面的写法等价于
Step(int xx, int s){
x = xx;
steps = s;
}
(这只是C++结构体初始化的一种方式)
队列也是一种运算受限的线性表,它的运算限制与栈不同,是两头都有限制,插入只能在表的一端进行(只进不出),而删除只能在表的另一端进行(只出不进),允许删除的一端称为队尾(rear),允许插入的一端称为队头 (Front),如图所示:
队列常用操作:
#include<queue>
queue<int> q; //参数是数据类型,这是队列的定义方式
q.empty()// 如果队列为空返回true,否则返回false
q.size() // 返回队列中元素的个数
q.pop() //删除队列首元素但不返回其值
q.front() // 返回队首元素的值,但不删除该元素
q.push(X) //在队尾压入新元素 ,X为要压入的元素
q.back() //返回队列尾元素的值,但不删除该元素