https://www.acmicpc.net/problem/11688
문제
세 정수 a, b, L이 주어졌을 때, LCM(a, b, c) = L을 만족하는 가장 작은 c를 찾는 프로그램을 작성하시오. LCM(a, b, c)는 a, b, c의 최소공배수이다.
입력
첫째 줄에 a, b, L이 주어진다. (1 ≤ a, b ≤ 106, 1 ≤ L ≤ 1012)
출력
첫째 줄에 c를 출력한다. 만약, 가능한 c가 없으면 -1을 출력한다.
문제 풀이
제목 그대로 최소공배수를 찾는 문제.
어떤 두 수를 각각 a,b라 하면 a * b = GCD(최대공약수) * LCM(최소공배수)인 것을 이용해 답을 구하는 문제이다.
a,b의 최소공배수(alpha)를 구하면, alpha와 c의 최대공배수가 L이 된다.
따라서 alpha * c = L * GCD(alpha, c)가 성립한다. 모든 수는 정수이므로 L이 alpha로 나누어떨어져야한다. 나누어떨어지지 않는다면 만족하는 c가 없으므로 -1을 출력한다.
위의 식을 다시 쓰면 c= (L/alpha) * GCD(alpha, c)이다. 반복문을 돌리며 alpha의 약수를 구하고 해당 약수가 최대공약수라 가정한 후 (L/alpha)를 곱하면 c를 구할 수 있다. c와 alpha의 실제 최대공약수를 구했을 때 우리가 최대공약수라 가정한 그 약수라면 식이 성립하므로 해당 c가 정답이다.
아래는 코드.
더보기
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
long long gcd(long long x, long long y)
{
if (y == 0)
{
return x;
}
else
{
return gcd(y, x % y);
}
}
long long lcm(long long x, long long y)
{
return x * y / gcd(x, y);
}
int main()
{
cin.tie(NULL);
ios::sync_with_stdio(false);
long long a, b, L;
cin >> a >> b >> L;
long long alpha = lcm(a, b);
long long k = L / alpha;
long long c = -1;
if (L % alpha != 0)
{
cout << "-1" << "\n";
}
else
{
vector<long long> v;
for (long long i = 1; i <= sqrt(alpha); i++)
{
if (alpha % i == 0)
{
v.push_back(i);
v.push_back(alpha / i);
}
}
sort(v.begin(), v.end());
bool isFound = false;
for (int i = 0; i < v.size(); i++)
{
c = k * v.at(i);
long long gcdAlphaC = gcd(alpha, c);
if (gcdAlphaC == v.at(i))
{
isFound = true;
break;
}
}
if (isFound == false)
{
cout << "-1" << "\n";
}
else
{
cout << c << "\n";
}
}
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준 25045] 비즈마켓 (C++) (0) | 2024.03.03 |
---|---|
[백준 1915] 가장 큰 정사각형 (C++) (0) | 2024.03.02 |
[백준 1509] 팰린드롬 분할 (C++) (0) | 2024.02.28 |
[백준 15990] 1, 2, 3 더하기 5 (C++) (0) | 2024.02.27 |
[백준 4386] 별자리 만들기 (C++) (0) | 2024.02.26 |