HDU-5974 A Simple Math Problem

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37753409/article/details/82926917

HDU-5974 A Simple Math Problem

题意:
给定两个数(a,b), 这两个数互质。 目前已知【x+y=a, x*y/gcd(x,y)=b】求(x, y)
分析:
先说结论:两个互质的数他们的乘积和加和也互质, 即有gcd(x, y) = gcd (a, b)
证明:
引论1: 若m, n互质, 那么m和m+n也互质
反证法:假设:若m, n互质,m和m+n不互质。
那么m和m+n一定存在一个公约数p,有:

 m = k1 * q
 (m + n) = k2  * q 

那么n可以表示为:

n = (m + n) - m = k2 * q - k1 * q = (k2 - k1) * q 

与m和n互质相矛盾。引论1证毕。
引论2: 唯一分解定理, 一个数可以分解成若干素数的乘积

开始证明:
设有两个互质的数(a, b)
根据引论2:

a = p1 * p2 * p3 * p4......* pn;
b = q1 * q2 * q3 * q4......*qm;

根据引论1:
a和a+b互质, b和a+b互质。
那么

a*b = p1 * q1 * p2 * q2 ..... pn *qm

所以:两个互质的数他们的乘积和加和也互质。
那么我们可以得到结论:

gcd(x, y)  = (a+b, a*b/gcd(a,b)) = gcd(a, b)

对于这道题:
我们可以得到

x + y = a
x * y / gcd (x, y) = b

假设g = gcd (x, y) = gcd (a, b)
那么

x + y = a
x * y = b*g

求解一元二次方程。

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define _ long long

_ gcd (_ a, _ b) {
    return b == 0 ? a : gcd (b, a%b);
}

int main () {
    _ a, b;
    while (scanf("%lld%lld", &a, &b) != EOF) {
        _ g = gcd (a, b);
        _ ag = a/g;
        _ bg = b/g;

        _ detla = (ag*ag) - 4*bg;
        if (detla < 0 || ((_)sqrt(detla)*sqrt(detla) != detla)) {
            printf ("No Solution\n");
            continue;
        }
       
        _ tdetla = sqrt(detla);
         
        _ y1 = (ag + tdetla)/2;
        _ y2 = (ag - tdetla)/2;
        bool flag = false;
        if ((y1 > 0 && y1 * 2 == ag + tdetla)) {
            _ x1 = ag - y1;
            if (x1 > 0) {
                printf ("%lld %lld\n", x1*g, y1*g);
                flag = true;
            }
        }

        if (!flag && y2 > 0 && y2 * 2 == ag - tdetla) {
            _ x2 = ag - y2;
            if (x2 > 0) {
                printf ("%lld %lld\n", x2*g, y2*g);
                flag = true;
            }
        }
        
        if (!flag) {
            printf ("No Solution\n");
        }
    }
    return (int)0;
}

猜你喜欢

转载自blog.csdn.net/qq_37753409/article/details/82926917