首页 > 代码库 > HDU 5974 A Simple Math Problem 数学题

HDU 5974 A Simple Math Problem 数学题

http://acm.hdu.edu.cn/showproblem.php?pid=5974

 

遇到数学题真的跪。。

 

题目要求

X + Y = a

lcm(X, Y) = b

 

设c = gcd(x, y);

那么可以表达出x和y了,就是x = i * c; y = j * c;

其中i和j是互质的。

所以lcm(x, y) = i * j * c = b

那么就得到两个方程了。

i * c + j * c = a;

i * j * c = b;

但是有一个c,三个未知数。

因为i和j互质,所以(i + j) 和 i * j 互质。

假设他们不互质,那么设那个数是x,有,i + j = m * x;  i * j = k * x;

那么有i和j都能整除x,(由第一条可以得到了),这和i和j互质矛盾。

gcd(a, b) = c了,

然后就能解一个一元二次方程。有解的时候要输出最小解,因为这样确保不会一个取了较大的解,另一个变了负数。

技术分享
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
LL a, b;
void work() {
    LL c = __gcd(a, b);
    LL B = a / c;
    LL C = b / c;
    LL diaota = B * B - 4 * C;
    LL t = inf / 2;
    if (diaota >= 0)
        t = (LL)sqrt(diaota);
    LL ans1 = B + t;
    LL ans2 = B - t;
    if (diaota < 0 || t * t != diaota || ((ans1 & 1) && (ans2 & 1))) {
        cout << "No Solution" << endl;
    } else {
        LL x, y;
        if (ans1 % 2 == 0 && ans2 % 2 == 0) { //优先最小解
            LL tans = min(ans1, ans2);
            tans /= 2;
            cout << tans * c << " " << (B - tans) * c << endl;

        } else if (ans1 & 1) {
            ans2 /= 2;
            x = ans2 * c;
            y = (B - ans2) * c;
            cout << ans2 * c << " " << (B - ans2) * c << endl;
        } else {
            ans1 /= 2;
            x = ans1 * c;
            y = (B - ans1) * c;
            cout << ans1 * c << " " << (B - ans1) * c << endl;
        }
//        if (x + y != a) while (1);
    }
}

int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    IOS;
    while (cin >> a >> b) work();
    return 0;
}
View Code

 

HDU 5974 A Simple Math Problem 数学题