新年快乐!
关于这道题,我想先引入咱学校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 ).
样例输出:
#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++提交的话编译器会报错.