标签:style blog http color io os ar strong for
Uva 11388 GCD LCM( 数论 )
题意: 求是否存在a,b 使得lcm(a,b) = L, gcd(a,b) = G,不存在输出-1,存在输出a,b,且a尽可能小
分析: 强行暴力是不可能的数据很大,要用llu,这里有两种思路
思路一: 由题意可知 a*b = G*L
保证a = G的倍数的情况下,枚举a
再判断G*L能否整除a,最后判断b是否为a的倍数。
a从G开始扫到sqrt(G*L)
//输入两个整数G,L //找出a,b 使得 gcd(a,b) = G lcm(a,b) = L //要求a尽可能小 //思路: /* 由题意 a*b = G*L 枚举a,b TLE 枚举a,然后在判定b 具体的是在保证a是g的约数的情况下,判断 G*L%a 是否为零,然后判断 b % g是否为零 思路二,直接证明。。。。 */ //#define BUG #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <vector> #include <list> #include <queue> #include <ctime> #include <iostream> #include <cmath> #include <set> #include <string> using namespace std; typedef long long LL; typedef unsigned long long ULL; #define INF 0x7fffffff #define MAX 0x3f3f3f3f void Orz() { int T; ULL t, G, L, a, b; scanf("%d",&T); while(T--) { scanf("%llu %llu",&G,&L); t = G * L; int flag = 0; for(a = G; a*a <= t; a+= G) { if(t % a == 0) { b = t / a; if(b % G == 0) { flag = 1; break; } } } if(flag) printf("%llu %llu\n",a,b); else printf("-1\n"); } } int main() { Orz(); return 0; }
思路二: 直接证明当存在 L*G = a*b 时,a=G, b=L
如果b%a != 0, 不存在解 (不会证明)
如果b%a == 0, 存在解,且最小解为a = G, b = L ;
可以想到 a要尽可能小,那么最小只能是两个数的最大公约数G
那么b 就要越大,,而最大是两个数的最小公倍数。
而恰好,a = G, b = L;
#include <cstdio> typedef unsigned long long ULL; void Orz() { int T; ULL G, L; scanf("%d",&T); while(T--) { scanf("%llu %llu",&G,&L); if(L % G) puts("-1"); else printf("%llu %llu\n",G,L); } } int main() { Orz(); return 0; }
标签:style blog http color io os ar strong for
原文地址:http://www.cnblogs.com/BigBallon/p/3995818.html