https://www.acmicpc.net/problem/2609
2609번: 최대공약수와 최소공배수
첫째 줄에는 입력으로 주어진 두 수의 최대공약수를, 둘째 줄에는 입력으로 주어진 두 수의 최소 공배수를 출력한다.
www.acmicpc.net
1. 최대공약수(Greatest Common Divisor) 구하기
유클리드 호제법(Euclidean algorithm)을 이용하는 방법입니다.
* 유클리드 호제법
a를 b로 나눈 나머지를 r이라고 할 때,
GCD(a,b) = GCD(b,r) 이다.
r이 0이면 그 때의 b가 최대공약수가 됩니다.
세 수의 최대공약수를 구해야할 때는 GCD(a,b,c) = GCD(GCD(a,b),c) 로 구할 수 있습니다.
즉, 먼저 두 수의 최대공약수를 구한 값과 c와의 최대공약수를 구하면 됩니다.
2. 최소공배수(Least Common Multiple) 구하기
두 수의 최소공배수는 GCD를 이용하여 구할 수 있습니다.
두 수의 최대공약수를 g라고 하고 최소공배수를 l이라고 할 때,
l=(a*b)/g 입니다.
[코드]
#include <iostream>
using namespace std;
int gcd (int a, int b) {
if (a % b != 0) { //나머지가 0이 아니라면
//재귀호출을 하는데 b는 a자리로, a%b는 b자리로 들어가면서 gcd를 구해나간다.
return gcd(b, a % b);
}else { //나머지가 0이라면 그때의 b가 정답이 된다.
return b;
}
}
int lcm (int a, int b) {
return a * b / gcd(a, b);
}
int main () {
int a, b;
cin >> a >> b;
cout << gcd(a, b) << '\n';
cout << lcm(a, b) << '\n';
return 0;
}
[결과]
24 18
6
72
https://www.acmicpc.net/problem/1934
1934번: 최소공배수
두 자연수 A와 B에 대해서, A의 배수이면서 B의 배수인 자연수를 A와 B의 공배수라고 한다. 이런 공배수 중에서 가장 작은 수를 최소공배수라고 한다. 예를 들어, 6과 15의 공배수는 30, 60, 90등이 있
www.acmicpc.net
최소공배수는 최대공약수를 이용하여 쉽게 구할 수 있습니다.
[코드]
#include <iostream>
using namespace std;
int gcd (int a, int b) {
if (b == 0) {
return a;
}else {
return gcd(b, a % b);
}
}
int main() {
int t;
cin >> t;
while (t--) {
int a, b;
cin >> a >> b;
cout << a * b / gcd(a, b) << '\n';
}
return 0;
}
[결과]
3 //input
1 45000 //input
45000
6 10 //input
30
13 17 //input
221
https://www.acmicpc.net/problem/9613
9613번: GCD 합
첫째 줄에 테스트 케이스의 개수 t (1 ≤ t ≤ 100)이 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있다. 각 테스트 케이스는 수의 개수 n (1 < n ≤ 100)가 주어지고, 다음에는 n개의 수가 주어진
www.acmicpc.net
이 문제도 최대공약수 연습문제입니다.
주의해야할 점이라면 결과값을 저장하는 sum 변수의 자료형입니다.
int형일 경우 통과가 되지 않으며, long long형일 경우 통과가 됩니다.
왜 long long 형이어야 하는지는 sum에 들어갈 수 있는 최대값을 대략적으로 계산해보아야 합니다.
최대값은 만들어질 수 있는 쌍의 최대 개수 * 각 쌍의 최대값이 될 것입니다.
1. 문제에서 각 테스트케이스마다 입력으로 주어지는 n의 값의 범위는 1 < n ≤ 100 라고 하였으니, 최대인 100으로 정합니다.
그러면 100개의 수의 전체 쌍의 개수를 구해야 합니다.
첫번째부터 시작해서 쌍을 만들면 99가지, 98가지, 97, ... 그리고 1까지의 합이 전체 쌍의 개수가 되므로 \(\frac{99*100}{2} = 4950\)개 입니다.
2. 모든 수의 입력이 1,000,000이고 모든 쌍의 최대공약수 값이 1,000,000이라는 최악의 상황을 가정.
1, 2번 값을 곱하면 \(4950 * 1000000 = 4,950,000,000\)이 되는데 49억은 int 자료형으로 담을 수 없습니다.
int형의 최대값은 \(2^{31}-1 = 2,147,483,647\)
즉, 21억정도가 되므로 long long으로 변경해야 테스트케이스를 통과할 수 있습니다.
[코드]
#include <iostream>
using namespace std;
int gcd (int a, int b) {
if (b == 0) return a;
else return gcd(b, a % b);
}
int main () {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int arr[101];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
long long sum = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
sum += gcd(arr[i], arr[j]);
}
}
cout << sum << '\n';
}
return 0;
}
[결과]
3 //input
4 10 20 30 40 //input
70
3 7 5 12 //input
3
3 125 15 25 //input
35
'Programming > Algorithms' 카테고리의 다른 글
[1476번] 날짜 계산 (0) | 2022.02.10 |
---|---|
[1978,1929,6588번] 소수 찾기, 에라토스테네스의 체, 골드바흐의 추측 (0) | 2022.02.09 |
[10430번] 나머지 (0) | 2022.02.08 |
[1158번] 요세푸스 문제 (0) | 2022.02.04 |