1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > GCD and LCM Aizu - 0005(辗转相除)+GCD LCM Inverse POJ - 2429(java

GCD and LCM Aizu - 0005(辗转相除)+GCD LCM Inverse POJ - 2429(java

时间:2021-03-30 12:15:31

相关推荐

GCD and LCM Aizu - 0005(辗转相除)+GCD  LCM Inverse POJ - 2429(java

题目:GCD and LCM Aizu - 0005

Write a program which computes the greatest common divisor (GCD) and the least common multiple (LCM) of given a and b.

Input

Input consists of several data sets. Each data set contains a and b separated by a single space in a line. The input terminates with EOF.

Constraints

0 < a, b ≤ 2,000,000,000

LCM(a, b) ≤ 2,000,000,000

The number of data sets ≤ 50

Output

For each data set, print GCD and LCM separated by a single space in a line.

Sample Input

8 6

50000000 30000000

Output for the Sample Input

2 24

10000000 150000000

分析:

求最大公约数和最小公倍数。。。

AC代码:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;typedef long long ll;ll n,m;ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}int main(){while(~scanf("%lld%lld",&n,&m)){ll a=gcd(n,m);printf("%lld %lld\n",a,n*m/a);}return 0;}

题意:

给你两个数a和b的最大公约数和最小公倍数。求a和b(当中在满足条件的情况下。使a+b尽量小)

题目: LCM Inverse POJ - 2429

Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b. But what about the inverse? That is: given GCD and LCM, finding a and b.

Input

The input contains multiple test cases, each of which contains two positive integers, the GCD and the LCM. You can assume that these two numbers are both less than 2^63.

Output

For each test case, output a and b in ascending order. If there are multiple solutions, output the pair with smallest a + b.

Sample Input

3 60

Sample Output

12 15

分析:

作者显然高估了读者的数学修养,我对数论一点都不熟悉,这题光靠前面介绍的一点数论皮毛无从下手,还是看了人家的代码才知道要用Rabin-Miller强伪素数测试和Pollard r因数分解算法。

基本思路是

(1)、(a / gcd) * (b / gcd) = lcm / gcd ,所以需要分解lcm / gcd 。将其分解为互质的两个数,如果这两个数之和最小,那么乘上gcd就是所求的答案。

(2)、但是题目数据太大,需要一个高效的素数检测算法,所以采用Rabin-Miller强伪素数测试

(3)、然后分解成质因子的n次方之积,从这些n次方中挑选一些作为x,剩下的作为y。枚举x和y的所有可能,找出最小值。

Rabin-Miller强伪素数测试和Pollard r因数分解算法

AC代码:

此代码并非我所写,我只理解了,由于时间紧迫,若有时间,回来钻研,这里放AC模板。

#include<stdio.h>#include<stdlib.h>#include<time.h>#include<math.h>#include<algorithm>using namespace std;typedef long long ll;#define MAX_VAL (pow(2.0,60))//miller_rabbin素性測试ll mod_mul(ll x,ll y,ll mo){ll t,T,a,b,c,d,e,f,g,h,v,ans;T = (ll)(sqrt(double(mo)+0.5));t = T*T - mo;a = x / T;b = x % T;c = y / T;d = y % T;e = a*c / T;f = a*c % T;v = ((a*d+b*c)%mo + e*t) % mo;g = v / T;h = v % T;ans = (((f+g)*t%mo + b*d)% mo + h*T)%mo;while(ans < 0)ans += mo;return ans;}ll mod_exp(ll num,ll t,ll mo){ll ret = 1, temp = num % mo;for(; t; t >>=1,temp=mod_mul(temp,temp,mo))if(t & 1)ret = mod_mul(ret,temp,mo);return ret;}bool miller_rabbin(ll n){if(n == 2)return true;if(n < 2 || !(n&1))return false;int t = 0;ll a,x,y,u = n-1;while((u & 1) == 0){t++;u >>= 1;}for(int i = 0; i < 50; i++){a = rand() % (n-1)+1;x = mod_exp(a,u,n);for(int j = 0; j < t; j++){y = mod_mul(x,x,n);if(y == 1 && x != 1 && x != n-1)return false;x = y;}if(x != 1)return false;}return true;}//PollarRho大整数因子分解ll minFactor;ll gcd(ll a,ll b){if(b == 0)return a;return gcd(b, a % b);}ll PollarRho(ll n, int c){int i = 1;srand(time(NULL));ll x = rand() % n;ll y = x;int k = 2;while(true){i++;x = (mod_exp(x,2,n) + c) % n;ll d = gcd(y-x,n);if(1 < d && d < n)return d;if(y == x)return n;if(i == k){y = x;k *= 2;}}}ll ans[1100],cnt;void getSmallest(ll n, int c){if(n == 1)return;if(miller_rabbin(n)){ans[cnt++] = n;return;}ll val = n;while(val == n)val = PollarRho(n,c--);getSmallest(val,c);getSmallest(n/val,c);}ll a,b,sq;void choose(ll s,ll val){if(s >= cnt){if(val > a && val <= sq)a = val;return;}choose(s+1,val);choose(s+1,val*ans[s]);}int main(){int T;ll G,L;while(~scanf("%lld%lld",&G,&L)){if(L == G){printf("%lld %lld\n",G,L);continue;}L /= G;cnt = 0;getSmallest(L,200);sort(ans, ans+cnt);int j = 0;for(int i = 1; i < cnt; i++){while(ans[i-1] == ans[i] && i < cnt)ans[j] *= ans[i++];if ( i < cnt )ans[++j] = ans[i];}cnt = j+1;a = 1;sq = (ll)sqrt(L+0.0);choose(0,1);printf("%lld %lld\n",a*G,L/a*G);}return 0;}

JAVA

import java.util.Scanner;public class Main{static long gcd(long a,long b){long tmp;while (b!=0){tmp = b;b = a % b;a = tmp;}return a;}public static void main(String args[]){Scanner cin = new Scanner(System.in);long a,b,c,i;while (cin.hasNext()){a = cin.nextLong();b = cin.nextLong();c = b/a;for(i=(long)Math.sqrt(c); i>=1; i--){if(c%i==0&&gcd(i,c/i)==1){System.out.println((a*i)+" "+(b/i));break;}}}}}

GCD and LCM Aizu - 0005(辗转相除)+GCD LCM Inverse POJ - 2429(java或【Miller Rabin素数測试】+【Pollar Rho整数分解】)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。