ACM-ICPC Asia Regional Contest HDU 5974 A Simple Math Problem(數論)

題目鏈接:點擊打開鏈接


題目大意:不說了.


解題思路: 

由題意,我們知道兩個條件:1.X+Y=a,2.lcm(X,Y)=b

我們從將X和Y分解出最大公約數入手,記:gcd(X,Y)=g;

則:

      X=g*k1,

      Y=g*k2,

     則條件1可以表示爲:a=g*(k1+k2) 記爲1式 ;

lcm(x,y)*gcd(x,y)=x*y條件2得:b=k1*k2*g  記爲2式;

因爲g爲X和Y的最大公約數,所以k1和k2互質,又可推得:k1+k2和k1*k2互質,推導過程如下:(下面這個過程自己拿紙和筆演練一下自然就懂了)


歐幾里得思想得:已知:x和y互質

因爲 gcd(x,(x+y)%x)=gcd( x,y ),則 gcd(x+y,x)=gcd(x,y)=1

gcd( x+y,y ) 同理得:gcd(x+y,y)=gcd(x,y)

所以得:x+y與x互質,與y互質


由一二式得:a/g和b/g互質所以a和b的最大公約數也爲g

得到結論:gcd(x,y)=gcd(a,b)=g;


回到題中: lcm(x,y)*gcd(x,y)=x*y  即:b*gcd(a,b)=x*(a-x) 用一元二次方程去求根,即爲所求x。


代碼如下:(細節問題在代碼中有解釋)

#include<iostream>
#include<cmath>
using namespace std;

int a,b;

int gcd(int a,int b)
{
    if(b==0)
        return a;
    else
        gcd(b,a%b);
}

int main()
{
    while(cin>>a>>b)
    {
        int c;
        int l=gcd(a,b);
        c=l*b;     //x*x-a*x-b*l=0
        long long tmp=a*a-4*c;
        if(tmp<0)    //如果沒有解,則沒有滿足條件的x、y。
            cout<<"No Solution"<<endl;
        else
        {
            long long x=(a+(int)sqrt(tmp))/2;     //計算對稱軸和x1、x2中點,你會發現另一個解的值我們所求的就是y,自己想想哦
            if(x*(a-x)==c)     //驗證上一步的開根號出來是不是整數
                cout<<a-x<<" "<<x<<endl;
            else
                cout<<"No Solution"<<endl;     //如果不是整數,則不滿足條件
        }
    }
    return 0;
}




~step by step 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章