【问题描述】
【解决思路】
按照题意,数字n只能通过乘2或减1转换成数字m。
如果n>m,则n只能通过减1得到m。
否则,可使用贪心算法。
将n多次乘2直至n>m,然后再通过“减1”进行调整得到m。
但问题在于减1的位置有多种,因为m可能在乘2的过程中进行减1。
所以,我们可以引入三个变量——
(1)mulcounter:乘2计数器,记录乘2的次数;
(2)subcounter:减1计数器,记录减1的次数;
(3)subpos:减1的位置,即表示在第(mulcounter - subpos + 1)次乘2之后进行减1。
在此基础上,解题步骤如下:
(1)多次乘2直至n>m。
(2)subpos初始化为mulcounter。
(3)如果n - m > 2^subpos,那么n就应该在第(mulcounter - subpos + 1)次乘2之后减1,否则subpos减1。当n = m时,循环结束。
【代码实现】
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int m, n;
cin >> n >> m;
int mulcounter = 0; // 记录乘2次数
while(n < m)
{
n *= 2;
mulcounter++;
}
int subcounter = 0; // 记录减1次数
int subpos = mulcounter; // 减1相对于乘2的位置
while(true)
{
while(n - m >= pow(2, subpos))
{
n -= pow(2, subpos);
subcounter++;
}
if(n == m)
break;
subpos--;
}
cout << mulcounter + subcounter <<endl;
return 0;
}