对于此LCM问题是否有更好的解决方案?

时间:2020-07-12 07:40:24

标签: algorithm math

  • 假设我们得到了一个数字N,它是一个正整数2 <= N <= 10^9

  • 我们需要找到两个整数AB,以便 -(A+B) = N, and LCM(A,B) is Minimum possible.

  • 例如,如果N = 9 then A = 3, B = 6是唯一有效的答案。

我现在想的是

  • 如果N is even,则A,B将是N/2
  • 如果N为奇数,则A,B将等于A is a perfect factor of B and A+B = N

我需要知道的

  • Am i doing right ?
  • Did i miss something ?
  • Is there any better solution for this ?

3 个答案:

答案 0 :(得分:1)

查找LCM最小的A,B与查找GCD最大的A,B相同。最大可能的GCD是N的最大因子(不包括N本身)。

因此,如果K是N的最大因子,则A = K,B = K *(N / K-1)是一种解决方案。所有解的形式均为A = jK,B = K(N / K-j),其中1 <= j

通过在[2,sqrt(N)]中找到将N除以最小的i,可以找到sqrt(N)时间中N的最大因数;那么最大的因素就是N / i。

例如,最大因数9(不包括9本身)是3,因此A = 3,B = 3 *(3-1)= 6。

答案 1 :(得分:0)

我相信简单的数学。

您给出的提示非常重要。

案例1:

如果N为偶数=> A = N / 2,则B = N / 2

案例2:

如果N是素数=> A = 1,B = N-1;

案例3:

如果N是奇数=>这很棘手。

现在,如果A + B = N,则A的最大值(考虑A <= B)为N/2

此外,为了最小化 A和B的LCM,LCM(A, B) = max(A, B) = B .... eq(1)

A + B = N .... eq(2)

B = d * A,其中d是任意正整数(来自eq(1)).... eq(3)

将eq(3)替换为eq(2),我们得到

A + d * A = N

A(1 + d)= N

A = N /(d + 1).... eq(4)

现在,目标是最小化LCM =>,这又是最小化max(A,B)= B

如果要最小化B,则需要最大化A(根据eq(4))

要最大化A,我们需要最小化(d + 1)。

因此,(d+1) = D = smallest factor of N,其中(D)> = 3且d = D-1。

最终答案,A = N /(d + 1),B = d * A

看看下面的实现对Codeforces做出了接受的判决:

#include <iostream>
#include <string>
#include <cmath>

typedef long long int LL;

bool isPrime(LL n)
{
    for(LL i = 2 ; i <= sqrt(n) ; i++ )
        if(n%i==0)return false;
    return true;
}


int main()
{
    int t;
    std::cin >> t; 

    while(t--){
        
        LL n, A, B;
        std::cin>>n;

        if( n % 2LL == 0 ) { 
            A = n/2LL ;
            B = n/2LL ; 
        }
        else if(isPrime(n)) {
            A = 1LL ;
            B = n-1LL ; 
        }
        else{
            
            LL D;
            for(LL i = 3; i <= sqrt(n) ; i++ )
            {
                if( n % i == 0) { 
                    D = i; 
                    break; 
                }
            }
            LL d = D - 1LL;
            A = n/(d+1LL);
            B = d*A;
        }

        std::cout<<A<<" "<<B<<std::endl;
    }
    return 0;
}

答案 2 :(得分:-1)

通过@Paul Hankin使用上述方法终于提出了解决方案,非常感谢。

C ++ 14解决方案。

ll n,A,B; cin >> n; // long long
        if( n % 2 == 0 ) { A = n/2 ; B = n/2 ; }
        else if(isprime(n)) { A = 1 ; B = n-1 ; }
        else
        {
            ll K;
            for(ll i = 3; i <= sqrt(n) ; i++ )
            {
                if( n % i == 0) { K = n/i ; break; }
            }
            A = K, B = n-K;
        }

以上程序中使用的素数检查功能

bool isprime(ll n)
{
    for( ll i = 2 ; i <= sqrt(n) ; i++ )
        if(n%i==0)return false;
    return true;
}