description
给定两个数字m、n,和两种操作分别是乘2、减1。从n变化到m最少需要多少步。变化的过程中不能出现负数。
Input
m和n的范围 (1 ≤ n, m ≤ 10^4),
Output
输出最少需要多少步
input
4 6
output
2
input
10 1
output
9
solution
- 隐式的BFS,注意m变化到n时下界>0,上界<2*n,或者<3*n也可以。
- 类似于构造一颗二叉树,左支是乘2,右支是减一。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
const int maxn = 1111;
bool vst[maxn * 1000];
int m, n;
using namespace std;
struct point
{
int num, cnt;
point()
{
num = cnt = 0;
}
};
int bfs()
{
memset(vst, false, sizeof(vst));
queue<point> q;
point now, tmp;
now.num = m, now.cnt = 0;
q.push(now);
vst[now.num] = true;
while (!q.empty())
{
now = q.front();
q.pop();
if (now.num == n)
return now.cnt;
tmp.num = now.num * 2;
tmp.cnt = now.cnt;
if (tmp.num > 0 && tmp.num < n * 2 && !vst[tmp.num])
{
tmp.cnt = now.cnt + 1;
q.push(tmp);
vst[tmp.num] = true;
}
tmp.num = now.num - 1;
tmp.cnt = now.cnt;
if (tmp.num > 0 && tmp.num < n * 2 && !vst[tmp.num])
{
tmp.cnt = now.cnt + 1;
q.push(tmp);
vst[tmp.num] = true;
}
}
}
int main()
{
// freopen("in.txt", "r", stdin);
while (~scanf("%d%d", &m, &n))
{
if (m >= n)
printf("%d\n", m - n);
else
printf("%d\n", bfs());
}
return 0;
}