hdu5505

题目:点击打开链接


题解:

给你2个数n,m,n每次都能乘以它的一个因子成为新的n,问你n至少乘多少次能够变成m,如果不能的话就输出-1。

如果n能变成m话,m肯定是n的整数倍,初始的n乘以多个因子变成m,那么那些因子的乘积就是m/n,也就是n*(m/n)=m,所以每次都找到k=gcd(n,m/n),然后n=n*k,(m/n)=(m/n)/k,直到n=m。

如果k=1的话,n也不能变成m.这题的坑点就是1<=m<=2^63,要用无符号长整型来表示。

不管是long long,还是__int64都是不够大的,因为它们所能表示的最大值为263-1

代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>

using namespace std;

unsigned long long gcd(unsigned long long a,unsigned long long b)
{
    return b?gcd(b,a%b):a;
}

int main()
{
    int t,ans,k;
    unsigned long long int m,n;
    cin>>t;
    while(t--)
    {
        ans=0;
        cin>>n>>m;
        while(n!=m)
        {
            if(n>m||(m%n!=0))
            {
                printf("-1\n");
                break;
            }
            k=gcd(m/n,n);
            if(k==1)
            {
                printf("-1\n");
                break;
            }
            n*=k;
            ans++;
        }
        if(n==m)
        {
            printf("%d\n",ans);
        }
    }

}


害羞

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值