您的位置:首页 > 其它

2018-01-12 HDU 5974 数论 GCD和LCM 的神奇性质

2018-01-13 10:29 429 查看
新年快乐!

关于这道题,我想先引入咱学校OJ上面的1221.

题目描述:

已知有 a 和 b , 其中 a = x + y , b = lcm( x , y ) ,  求解 x 和 y 的平方和.

鉴于这个并不是这篇文章的重点,我就写写这个题目的关键点:

gcd( x , y ) = gcd( a , b )

先给证明:设 gcd( x , y ) = g .

则有 x = g * x'  ,  y = g * y' , 鉴于最大公因数的性质可以知道 x' 和 y' 是互质的.

同时 x * y = x' * y' * g * g , 那么 b = lcm( x , y ) = x' * y' * g.

自然也有 a = g * ( x' + y' ).

然后就是证明a和b的最大公因数就是g:

即证明两个互质的数的积( x' * y' )和它们的和( x' + y' )互质

#1 x' 和 y'都不为1

在此我们使用反证法,假设有其他的公因数,即不互质.

由于 x' * y' 仅有 x' 和 y' 这两个非1非本身的因数,那么公因数必定是挑两个数里面的因子然后相乘.

但是很明显 x' + y' 并没有这些因子(不妨试试找个非 1 的因子除一下, 如果 x' 能被除尽,那么 y' 必定不能被除尽, 因为它们互质)

矛盾,所以两个互质的数的积( x' * y' )和它们的和( x' + y' )互质.

#2 x' 和 y'有一个是1

x' * y'是质数, 且 x' + y' = x' * y' + 1 ,很明显互质.

#3 x' 和 y'都是1

x' * y' = 1 , 1 和任何数互质.

结合 #1 , #2 , #3, 得出两个互质的数的积( x' * y' )和它们的和( x' + y' )互质,

即结论 gcd( a , b ) = g 成立,证毕.

所以 gcd( a , b ) = g = gcd( x , y ).

那这就热闹了,

x + y = a

x * y = b * gcd( x , y ) = b * gcd( a , b )

所以 x^2 +y^2 = ( x + y )^2 - ( x * y )*2

当然了,这个式子要带入一下,避免减少精度(这个很烦人的)

代码如下

#include <stdio.h>
#include <stdlib.h>

int gcd1(int a,int b)
{
int res;
if(b==0)
return 0;
res=a%b;
while(res)
{
a=b;
b=res;
res=a%b;
}
return b;
}

int main()
{
int a,b,gcd,T;
long long int res;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
res=0;
scanf("%d%d",&a,&b);
gcd=gcd1(a,b);
res=a*a-2*b*gcd;
printf("%lld\n",res);
}
}
return 0;
}

然后才是HDU的5974
题目描述:

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 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.

输出:

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

样例输入:

6 8
798 10780

样例输出:
No Solution
308 490

眼不眼熟啊,什么你说不眼熟,我告诉你 Least Common Multiple 的缩写是lcm,现在眼熟了吧
已知 X * Y 和 X + Y , 求 X 和 Y, 这个是一个初中(还是高中级别的?)的解方程题目,比刚刚那个平方和稍微麻烦一点点,带入消元就是一个一元二次方程组啦
代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <iostream>
using namespace std;

int main()
{
long long a,b,x,y,gcdd;
while(scanf("%lld%lld",&a,&b)!=EOF)
{
gcdd=__gcd(a,b);
a=a;
b=b*gcdd;
if((a*a-4*b)<0)
printf("No Solution\n");
else
{
x=(a+sqrt(a*a-4*b))/2;
y=a-x;
if((x*y)==(b))
printf("%lld %lld\n",y,x);
else
printf("No Solution\n");
}
}
return 0;
}

有没有惊喜的发现求GCD的函数是系统自带的? 准确的说是编译器自带的函数 ( 并不是包含在哪个头文件里哈 ) , 好像是GNU那边才有, 因此在HDU上面需要以G++提交, 以C++提交的话编译器会报错.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  GCD LCM 数论