HDU - 5974 A Simple Math Problem (数论 GCD)

 

题目描述:


Given two positive integers a and b,find suitable X and Y to meet the conditions:
X+Y=a
Least Common Multiple (X, Y) =b

Input

Input includes multiple sets of test data.Each test data occupies one line,including two positive integers a(1≤a≤2*10^4),b(1≤b≤10^9),and their meanings are shown in the description.Contains most of the 12W test cases.Output For each set of input data,output a line of two integers,representing X, Y.If you cannot find such X and Y,output one line of "No Solution"(without quotation).

Sample Input

6 8
798 10780

Sample Output

No Solution
308 490

题目大意:给定正整数a,b;求两个正整数 x,y,使得 x + y == a && LCM(x,y) == b, 如果找不到则输出No solution.

题解:由于test case 和 a,b规模都很大,不能使用暴力,必然是通过数学方法直接求解。

 

不妨设x = ki, y = kj; gcd(x,y) = k

易知 i,j互质 (如果不互质则gcd必然大于k)

gcd(a,b) = gcd( k*(i+j) , k*(i*j) ) 

由于i,j互质,则(i+j)和 (i*j)必然互质,证明如下:

对于i的任意因子p(1除外),i % p = 0,  (i*j) % p = 0

(i+j) % p = (i%p + j%p) % p = j%p, 由于i,j互质则p必然不是j的因子,所以 p 不是 (i+j) 的因子

所以对于i的所有因子(1除外)i+j都没有,但i*j都有;同理对于j的所有因子(1除外),i+j也没有,但i*j都有

所以i*j的所有因子(1除外),i+j都没有  即 (i+j) , (i*j) 互质

我们可以得出以下结论:

(1)如果 i,j互质,那么i 和(i+j) 互质,j和(i+j)互质

(2)如果 i,j互质,那么(i+j)  和(i*j)互质

 

对于此题我们推出了gcd(a,b) =  gcd(x,y) = k

原方程:LCM(x,y) = x*y / gcd(x,y) = b             xy = bk = b*gcd(a,b)

又有x + y = a , a,b已知

可以把y表示成x带入解一元二次方程; 

也可以用(x-y)2 = (x + y)2 - 4xy求出x - y进而求出x和y

 

 

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

using namespace std;

long long gcd(long long a,long long b)
{
    return a == 0 ? b : gcd(b % a, a);
}
int main()
{
    long long a,b;
    ios::sync_with_stdio(false);
    while(cin>>a>>b)
    {
        long long c = gcd(a,b);
        long long xy = c*b;
        long long t = a*a-4*xy;
        long long t1 = sqrt(t);
        long long x = (t1+a)/2;
        long long y = (a-x);
        if((x/gcd(x,y)*y!=b))
        {
            cout<<"No Solution"<<endl;
            continue;
        }
        if(x<y)
        {
            cout<<x<<" "<<y<<endl;
        }
        else
        {
            cout<<y<<" "<<x<<endl;
        }
    }
    return 0;
}

 

posted @ 2018-09-05 23:40  西风show码  阅读(237)  评论(0编辑  收藏  举报