Acwing 4300. 两种操作

给定一个正整数 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;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值