给定一个正整数 n,我们希望你可以通过一系列的操作,将其变为另一个正整数 m。
操作共分两种:
1.将当前的数乘以 2
2.将当前的数减去 1
要求,在变换过程中,数字始终为正。
请你计算,所需要的最少操作次数。
输入格式:
一行,两个不同的正整数 n 和 m。
输出格式:
一个整数,表示所需的最少操作次数。
数据范围:
前 6个测试点满足 1≤n,m≤10。
所有测试点满足 1≤n,m≤10000。
输入样例1:
4 6
输出样例1:
2
输入样例2:
10 1
输出样例2:
9
1.贪心
证明:当n>m 时 ,且m为偶数时,则/2.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+100;
typedef pair<int,int> PII;
#define x first
#define y second
#define INF 0x3f3f3f3f
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
const int mod=1e9+7;
int n,m;
int cnt;
int main()
{
cin>>n>>m;
if(n>=m) cout<<n-m<<endl;
else //反推
{
while(n<m) //n>=m 就可以转换为前两种情况
{
if(m&1) m++; //如果m为奇数,则不能/2,n*2变过来的一定是偶数.
else m/=2; // 为偶数则可以/2.
cnt++;
}
cout<<cnt+n-m<<endl; //转换为前两种情况
}
return 0;
}
2.搜索 宽搜
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=20100;
typedef pair<int,int> PII;
#define x first
#define y second
#define INF 0x3f3f3f3f
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
const int mod=1e9+7;
int n,m;
int d[N],q[N];
int main()
{
cin>>n>>m;
int hh=0,tt=0;
memset(d,0x3f,sizeof d); //初始数组,方便更新
d[n]=0; // 起点为0.
q[0]=n; //起点加入队列.
while(hh<=tt)
{
int t=q[hh++];
int change[]={t-1,t*2}; //用一个数组表示两种操作,方便操作
for(auto i:change)
{
if(i>=1&i<N&&d[i]>d[t]+1) // 2*n<2*m 最大枚举到2e4
{
d[i]=d[t]+1; //满足条件就更新
q[++tt]=i; //加入队列
}
}
}
cout<<d[m]<<endl;
return 0;
}