1215 Finding LCM
题意:
L=LCM(a,b,c) ,输入abL,求满足条件的最小c。
输入:
T组测试样例。
3
3 5 30
209475 6992 77056500
2 6 10
输出:
Case 1: 2
Case 2: 1
Case 3: impossible
思路:
前置1:
首先,对于L=lcm(a,b,c)。可以进行一个等价代换:
lcm(a,b,c)=lcm(lcm(a,b),c)
记lcm(a,b)=t,则L=lcm(t,c)
此时 L,t都已知。且lcm(t,c)=t∗c/gcd(t,c)=L
前置2:
由唯一分解定理可知:
t=pa11∗pa22∗⋅⋅⋅pann
c=pb11∗pb22∗⋅⋅⋅pbnn
L=lcm(t,c)=pmax(a1,b1)1∗pmax(a2,b2)2∗⋅⋅⋅∗pmax(an,bn)n
综述:
由前置2可以得到 若c使得lcm(t,c)=L ,则L一定可以整除t,否则c便不满足条件。
记:
x=Lt
这里用实际例子解释比较容易理解一点: a=3,b=5,L=90
此时 t=15,x=6
L=2∗32∗5
t=3∗5
肉眼可见的此时c应该是2∗32 才可以满足lcm(t,c)=L(前置2)
而 x=Lt=2∗3,此时我们可以发现 x距我们要找的c差一个3。
相当于L中有p个3, t中有q个3.而x中有p−q个3 ,我们便对 t和x求q次最大公约数。
每次对t除3,对x成3。 最终x中3的次数为p,也就是L中3的次数。 当gcd(t,x)=1的时候,x便为我们要求的c
代码:
#include <cstdio>
typedef long long LL;
using namespace std;
LL a, b, L;
LL gcd(LL a, LL b){
if(b == 0){
return a;
}
return gcd(b, a % b);
}
LL lcm(LL a, LL b){
return a / gcd(a, b) * b;
}
int main(){
int T;
scanf("%d", &T);
for(long long Case = 1; Case <= T; ++ Case){
printf("Case %lld: ", Case);
scanf("%lld %lld %lld", &a, &b, &L);
LL t = lcm(a, b);
if(L % t){
puts("impossible");
}
else{
LL res = L / t;
while(1){
LL d = gcd(res, t);
if(d == 1){
break;
}
res *= d;
t /= d;
}
printf("%lld\n", res);
}
}
return 0;
}
m
%%%