2016/41届ACM/ICPC大连现场赛D题&hdoj5974



A Simple Math Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 697    Accepted Submission(s): 257


Problem Description

Given two positive integers a and b,find suitable X and Y to meet the conditions:
X+Y=a
Least Common Multiple (X, Y) =b
 

Input
Input includes multiple sets of test data.Each test data occupies one line,including two positive integers a(1��a��2*10^4),b(1��b��10^9),and their meanings are shown in the description.Contains most of the 12W test cases.
 

Output
For each set of input data,output a line of two integers,representing X, Y.If you cannot find such X and Y,output one line of "No Solution"(without quotation).
 

Sample Input
  
  
6 8
798 10780
 

Sample Output
  
  
No Solution
308 490
 

Source

解题思路:
数论题,用到的结论是若i,j互质,则i+j,i*j互质
x+y=a, lcm(x,y)=b, a b已知,求x,y是否存在,存在即按升序输出,不存在即输出 No Solution

因为lcm(x,y)=b,即 b=x*y/gcd(x,y)
1.a=x+y
2.b=x*y/gcd(x,y)
观察两个等式,只有先从gcd(x,y)入手看看
设gcd(x,y)=c
则 x可表示为 c*i
y可表示为c*j
(c显然分别x,y的因子,所以这样的表示是成立的)
同时 因为 c是x,y的最大公约数,则 i和j,显然是互质的(换句话说,如果i,j不互质,那么c就不是x,y的最大公约数)

因为 x=c*i ;
y=c*j
带入 a,b的等式:
a=c(i+j)
b=c * c *i *j /c=cij
那么可以得到 gcd(a,b)=gcd(c(i+j),cij)
根据数论定义,若i,j互质,则i+j,i*j互质
可知a,b公因子部分为c
gcd(a,b)=c=gcd(x,y)

这样显然:
1.a=x+y
2.b=x*y/gcd(x,y)=x * y/gcd(a,b)//a,b已给出,求个gcd即可

x=a-y
(a-y)y/gcd(a,b)=b,设gcd(a,b)=k

-y*y+ay-bk=0;

(系数都已知,根据求根公式,解一个一元二次方程即可)

题目要求整数解,
所以用解出来的跟、根,带入原来的两个等式验证是否成立,成立即输出解得的根,否则
No Solution

AC代码:

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long  LL;
LL gcd(LL a,LL b){
    return b?gcd(b,a%b):a;

}
int main(){
    long long  a,b,c,A,B;
    while(scanf("%I64d%I64d",&A,&B)!=EOF){
        LL g=gcd(A,B);

        a=-1;
        b=A;
        c=(-1)*(B*g);
        LL dlt=sqrt(b*b-4*a*c);
        LL x=-1*b+dlt;
        x=x/(2*a);    
        LL y=-1*b-dlt;
        y=y/(2*a);

        if(x+y==A)
        {
            if(x*y==B*g){
                LL t;
            if(a>b){
                t=a;
                a=b;
                b=t;

            }
            cout<<x<<" "<<y<<endl;
            }
            else
            {
            cout<<"No Solution"<<endl;    
            }
        }
        else
        cout<<"No Solution"<<endl;
    }



    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值