hdu5974——A Simple Math Problem(gcd推导+数学+解方程组)

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

题意:求满足X+Y=a,lcm(X,Y)=b的第一对X Y(a,b给定),没有就 No Solution

思路:

先证明互质的数的乘积和他们的和互质

证明:设这两个数为p ,q
M=p+q N=pq
假设M,N不互质,则有:M=aN或 N=aM (a>1且a为自然数)
当M=aN时,
p+q=apq
p= q(ap-1)
p/q=ap-1
因为p,q互质,所以p/q为1或非整数
当p/q=1时,ap=2(不符)
当p/q为非整 数时 ,ap-1为整 数 ,矛盾即M不等于aN
同理可证N不等于aM
所以 M,N互质

X+Y=a => X/gcd(X,Y)+Y/gcd(X,Y)=a/gcd(X,Y) (1)

LCM(X,Y)=b => X*Y/gcd(X,Y)=b =>X/gcd(X,Y)*Y/gcd(X,Y)=b/gcd(X,Y) (2)

X/gcd(X,Y)和Y/gcd(X,Y)互质,a/gcd(X,Y)和b/gcd(X,Y)也就互质。

即gcd(a,b)=gcd((X+Y)/gcd(X,Y),(X/gcd(X,Y)*(Y/gcd(X,Y))*gcd(X,Y)=1*gcd(X,Y)=gcd(X,Y)

那么这题也就6了~

求X-Y的平方=>(X-Y)^2=(X+Y)^2-4*(XY)=a^2-4*gcd(a,b)*b>=0 判断下有没有解

做到这里我懵了一会,然后又让我想到了,我有了X-Y,我是不是就能用X+Y=a去判断lcm(X,Y)=b是否有整数解了。注意,X-Y的平方开根是double,令a1=(a-(X-Y))/2=Y,b1=(a+(X-Y))/2=X;(a1和b1)是double强制转化成整型来的。这样a1,b1只要任一满足 狗*(a-狗)==b*gcd(a,b)就有解,否则没有。。。做到这里我想,这题难道能暴力? 能暴力我也不敢交了,因为上边结论我推了半天。。

#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <algorithm> #include <vector> #include <map> #include <string> #include <stack> using namespace std; typedef long long ll; #define PI 3.1415926535897932 #define E 2.718281828459045 #define INF 0xffffffff//0x3f3f3f3f #define mod 1000000007 const int MOD=1e9+7; const int M=1005; int n,m; ll gcd(ll a,ll b){     if(b==0)return a;     return gcd(b,a%b); } int main(){     int i,j,k,t;     ll a,b,tmp;     double sq;     while(cin>>a>>b){         tmp=gcd(a,b)*b;         sq=sqrt(a*a-4*tmp);         if(a*a<4*tmp){             printf("No Solution\n");             continue;         }         ll a1=(a*1.0-sq)/2.0;         ll b1=(a*1.0+sq)/2.0;         if(a1*(a-a1)==tmp)         {             printf("%lld %lld\n",a1,a-a1);             continue;         }         else if(b1*(a-b1)==tmp){             printf("%lld %lld\n",b1,a-b1);             continue;         }         else printf("No Solution\n");     }     return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值