Problem 005 : Smallest multiple (5%)
Description
original
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
간략해석
1에서 20의 최소공배수를 구하여라.
Idea & Algorithm
naive idea
반복문을 쭉 돌리면서 1부터 수가 나누어떨어지는가를 체크하는 방법이 있지만 이 경우에 최악의 케이스 경우에는 20!까지 연산해야한다.
advanced idea
lcm(a,b,c) = lcm(lcm(a,b),c)을 이용하자.
lcm은 결합법칙이 성립한다. 그렇다면 1부터 쭉 lcm을 연속적으로 계산하면 된다. lcm(a,b) = a*b/gcd(a,b)임을 사용하면 쉽게 풀 수 있다.
최소공배수의 성질
집합 $G$에서 최소공배수에서 어떤 소수 $p$는 $p^e (gcd(\frac{LCM}{p^e}, p^e) = 1)$의 형태로 존재한다. 어렵게 썼지만 그냥 소수 $p$가 $e$개 있다는 것이다.
그리고 이 $e$는 $G$의 원소들 중, $p$를 소인수로 가지는 수 중 가장 많이 포함한 경우 $e$개임을 의미한다.
즉, $G$원소들을 소인수분해해서 각 소인수의 최대개수들의 구해서, 모두 곱해주면 된다.
+ gcd 구하는법
유클리드 호제법을 이용하여 구하면 된다. 이는 projecteuler 시작이라는 post에 올려두었다. 아니면 아래 코드를 참조하면 된다.
source code
20!이 longlong범위이므로 단순 구현으로 첫번째 방법을 사용했다.
#include <stdio.h>
#define ll long long
ll gcd(ll a, ll b){
if(a%b==0) return b;
else return gcd(b, a%b);
}
ll lcm(ll a, ll b){
return (a/gcd(a,b)) * b;
}
int main(){
ll ans = 1;
for(ll i = 2; i <= 20 ; i++) ans = lcm(ans,i);
printf("%lld",ans);
}
Leave a Comment