版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}