D. Another Problem About Dividing Numbers

You are given two integers a and b. In one turn, you can do one of the following operations:

Take an integer c (c>1 and a should be divisible by c) and replace a with ac;
Take an integer c (c>1 and b should be divisible by c) and replace b with bc.
Your goal is to make a equal to b using exactly k turns.

For example, the numbers a=36 and b=48 can be made equal in 4 moves:

c=6, divide b by c ⇒ a=36, b=8;
c=2, divide a by c ⇒ a=18, b=8;
c=9, divide a by c ⇒ a=2, b=8;
c=4, divide b by c ⇒ a=2, b=2.
For the given numbers a and b, determine whether it is possible to make them equal using exactly k turns.

Input
The first line contains one integer t (1≤t≤104). Then t test cases follow.

Each test case is contains three integers a, b and k (1≤a,b,k≤109).

Output
For each test case output:

“Yes”, if it is possible to make the numbers a and b equal in exactly k turns;
“No” otherwise.
The strings “Yes” and “No” can be output in any case.

Example
inputCopy
8
36 48 2
36 48 3
36 48 4
2 8 1
2 8 2
1000000000 1000000000 1000000000
1 2 1
2 2 1
outputCopy
YES
YES
YES
YES
YES
NO
YES
NO
题目大意:就是求两个数a,b是否能在k次变换内使得两数相同。
题解:就是求两个数最多可有几个数相乘而得,但k=1时应特殊判断。
下面是超时代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
int count(int a)
{
    int sum=0,i;
    for(i=2;i<=sqrt(a);i++)
    {
        while(a%i==0)
        {
            sum++;
            a/=i;
        }
    }//这几行代码就是求出两个数最多可有几个数相乘而得
    if(a>1)
        sum++;//这主要是
    return sum;
}
int main()
{
    int t,x,y,a,b,k;
    cin>>t;
    while(t--)
    {
        cin>>a>>b>>k;
        if(k==1)
        {
            if(a!=b&&(__gcd(a,b)==a||__gcd(a,b)==b))
                printf("YES\n");
            else
                printf("NO\n");
        }
        else
        {
            int x=count(a);
            int y=count(b);
            if(k>=2&&k<=x+y)
                printf("YES\n");
            else
                printf("NO\n");
        }
    }
    return 0;
}

下面是AC代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
int count(int a)
{
    int sum=0,i;
    for(i=2;i*i<=a;i++)
    {
        while(a%i==0)
        {
            sum++;
            a/=i;
        }
    }
    if(a>1)
        sum++;//最后剩下的是质数,所以加上它本身作为一个因子。
    return sum;
}
int main()
{
    int t,x,y,a,b,k;
    cin>>t;
    while(t--)
    {
        cin>>a>>b>>k;
        if(k==1)
        {
            if(a!=b&&(__gcd(a,b)==a||__gcd(a,b)==b))
                printf("YES\n");
            else
                printf("NO\n");
        }//k=1时的分类。
        else
        {
            int x=count(a);
            int y=count(b);
            if(k>=2&&k<=x+y)
                printf("YES\n");
            else
                printf("NO\n");
        }
    }
    return 0;
}

对比可以看出,两个代码仅查了是ii<=a还是i<=sqrt(a),可以看出,ii<=a相比于后者更快一些。所以以后建议用前者。
下面是我做题时写的代码,但错了。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
 
bool sushu(int n)
{
    int i;
    if(i==1) return 0;
    for(i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
            return 0;//0表示不为素数。
    }
    return 1;
}
long long gcd(long long a,long long b)
{
     if(a<=0 || b<=0) return 0;    //如果传进来的参数小于0则返回0
     else if(a%b==0) return b;           //如果b能被a整除则b就是最大公约数
     else
        return gcd(b,a%b);              //递归 调用函数本身
}
int main()
{
    long long n,m,k,i,j;
    long long t;
    cin>>t;
    while(t--)
    {
        long long sum2=2,min1,sum1=2;
        cin>>n>>m>>k;
        long long g=gcd(n,m);
        if(g==n&&g!=m)
            min1=1;
        else if(g!=n&&g==m)
            min1=1;
        else
            min1=2;
        for(i=2;i<=sqrt(n);i++)
        {
            while(n%i==0)
            {
                sum1++;
                n=n/i;
            }
            if(n<i)
                break;
        }
        for(j=2;j<=sqrt(m);j++)
        {
            while(m%j==0)
            {
                sum2++;
                m=m/j;
            }
            if(m<j)
                break;
        }
        if(k<=sum1+sum2-2&&k>=min1)
          printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

可以看出这个代码写的很冗长,而且错误点很多。而且考虑的时候不是按k考虑的,而时生硬的一种一种情况的列举,很容易错,而且,没有用gcd函数,而是手写gcd,多此一举,这里我感觉应该是求两者最大的相乘时错了。所以这个题学到的还是挺多的。当然,此题未考虑k=0的情况,如果改变了k的范围,此题多加一个特判就行了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值