[week10]签到题——Game23

题意

东东在玩游戏“Game23”。

在一开始他有一个数字n,他的目标是把它转换成m,在每一步操作中,他可以将n乘以2或乘以3,他可以进行任意次操作。输出将n转换成m的操作次数,如果转换不了输出-1。

Input

输入的唯一一行包括两个整数n和m(1<=n<=m<=5*10^8).

Output

输出从n转换到m的操作次数,否则输出-1.

输入样例

Simple Input 1

120 51840

Simple Input 2

42 42

Simple Input 3

48 72

输出样例

Simple Output 1

7

Simple Output 2

0

Simple Output 3

-1

提示


分析

一道简单的思维题。

  • 题目分析

两个数字从a转换,只能通过乘以2和3来实现。

显然,a和b之间一定满足以下条件:

  • b一定能整除a
  • b一定大于a的2倍或a的3倍或b等于a
  • b一定能整除2或整除3

只要这些条件不满足,首先就肯定判定这两个数一定无法实现转换。

其次考虑,如果a和b之间可以转换,就代表着a乘以一个因子可以得到b。而这个因子只由多个2和3中的一个或两个组成。

所以,先得到这个因子,将该因子逐层整除。如果该因子只能整除2,则除以2;如果只能3,则除以3;如果两者皆可整除,则除以6。

直到该因子等于1,说明该因子符合要求;或出现2和3都无法整除时,说明该因子含有除2和3以外的因子,不符合要求。

在处理该因子的过程中记录转换次数,显然每除掉一个2或3就代表着转换时乘上一个2或3,则转换次数+1,而除掉一个6代表转换时需要乘以一个2和一个3,因此转换次数+2。


总结

  1. 我总是在拿到题的一开始想得很复杂👐🏼最开始几次提交都wa,搞得我一头雾水,结果洗了个澡出来就知道自己有多蠢了👋
  2. 注意a和b相等的特殊情况!

代码

//
//  main.cpp
//  lab1
//
//

#include <iostream>
#include <queue>
#include <map>
using namespace std;

int n = 0,m = 0,res = 0;

int main()
{
    ios::sync_with_stdio(false);
    
   
    
    cin>>n>>m;
    
    //如果不能整除或本身小于n或小于2倍也小于3倍或本身无法整除2或3,肯定不行
    //如果相等,直接输出0
    if( m == n )
    {
        cout<<0<<endl;
    }
    else if( m % n != 0 || m < n ||( m < 2 * n && m < 3 * n) || (m % 2 != 0 && m % 3 != 0 ))
        cout<<-1<<endl;
    else
    {
        
        m /= n;     //得到它们的商
        
        //如果能转换,则商一定有且仅有2、3中的一个或两个相乘所得
        while(1)
        {
            if( m % 2 == 0 && m % 3 == 0 )      //若同时能整除,直接除以6
            {
                m /= 6;
                res += 2;       //转换次数+2
            }
            else if( m % 2 == 0 )       //只能整除2
            {
                m /= 2;
                res += 1;
            }
            else if( m % 3 == 0 )       //只能整除3
            {
                m /= 3;
                res += 1;
            }
            else if( m % 2 != 0 && m % 3 != 0 )     //若都不能整除,说明无法转换
            {
                cout<<-1<<endl;
                return 0;
            }
            
            if( m == 1 )                //若最后得到1,说明转换成功
            {
                cout<<res<<endl;
                return 0;
            }
            else if( m < 1 )            //否则失败
            {
                cout<<-1<<endl;
                return 0;
            }
        }
    }
    
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天翊藉君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值