A Simple Math Problem HDU - 5974(数论,gcd相关的公式推导,好题)

题意:A=X+Y 且X与Y的最小公倍数是B,已知A、 B,求X、Y。

题解:参考博客先说几个才知道的性质

性质1:如果k1,k2互质,则k1+k2与k1*k2也是互质的(具体证明可以点击上面的博客,用的是反正法)。

性质2:对于x,y的g(即gcd),必有k1*x=g,k2*y=g且k1,k2互质,同样的如果存在x/g与y/g互质,则说明g是x,y的最大公约数(比如如a/g,b/g互质那么说明g也是a和b的最大公约数)。

对于本题其实关键在于求解gac(x,y),这里的gcd(x,y)等于gcd(a,b),推导如下:

根据题目条件我们可以得到两个式子:

                                       x+y=a;

                                       xy=b*g;

将x*k1=g,x*k2=g带入化简可以得到:

                                       k1+k2=a/g;

                                       k1*k2=b/g;

由性质1和性质2可知 g也是a和b得最大公约数。联立最初的两个式子我们可以得到x*x-a*x+b*g=0写个代码解方程就行了。

AC代码:

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false);cin.tie(0); 
using namespace std;
const int maxn=1e6+5;
typedef long long ll;
ll gcd(ll a,ll b){
	if(a<b)swap(a,b);
	if(a%b)return gcd(b,a%b);
	else return b;
}
int main() {
	IOS;
	ll a,b;
	while(cin>>a>>b){
		ll dita=a*a-4*b*gcd(a,b);
		ll p=sqrt(dita);
		if(dita<0||p*p!=dita){
			cout<<"No Solution"<<endl;
			continue;
		}
		ll x1=(a+p)/2;
		ll x2=(a-p)/2;
		cout<<min(x1,x2)<<" "<<a-min(x1,x2)<<endl;
	}
}

猜你喜欢

转载自blog.csdn.net/Alanrookie/article/details/107744377