티스토리 뷰
이 문제는
수빈이의 현재 위치와
동생들의 위치사이의 간격끼리의 GCD(최대공약수)를 구하는 문제이다
그래서
GCD를 구하는 알고리즘을 잘짜야지 통과가 되는데
I=2부터부터 해당 수 까지 일일히 찾으니
너무 오래걸린다
구글링해보니
GCD를 구하는 유명한 알고리즘
유클리드 호제법이라는게 있어서
사용해보았다
유클리드 호제법이란
수 A,B 가 있을때(A>B)
A%B한 값이 0이 될때까지 반복하면
A값이 최대공약수라는 알고리즘이다
증명은 딱히 필요없고
어떻게 그게 되는지 확인해보겠다
A=12, B=8이라 가정
First step
A=12, B=8
Second step
A=12%8, B=8 -> A=4, B=8 -> A=8, B=4
Third step
A=8%4, B=4 -> A=0, B=4 -> A=4, B=0 -> 4가 최대공약수
어째서 이렇게 되는지 신기하긴 한데
밑에글을 보면 조금 이해가 된다
유클리드 호제법에 따르면 a라는 수와 b라는 수가 있을 때 a와 b의 최대공약수(Greatest Common Divisor) gcd(a,b)는 gcd(b, a%b)라고 표현할 수 있다. gcd(a,b)를 a가 b보다 더 크다고 가정하면 q라고 가정했을 때, a = a1*q 로 b = b1*q로 표현 가능하다. 만약 a-b를 하게되면 a-b = (a1-b1)*q가 된다. a1-b1는, a가 b보다 크다고 가정했기 때문에 서로소 관계이고 따라서 a-b는 반드시 a보다 작은 값이 된다. 그리고 가장 중요한 점은 a-b가 q라는 최소공배수를 포함하고 있다는 사실이다.
따라서 a와 b의 최대공약수를 구하는 문제가 b와 a-b 사이의 최대공약수배수를 구하는 문제로 치환하여 해결할 수 있다.
코드를 살펴보면, a-b가 아니라 a%b로 하였는데 이유는 a-b를 여러번 하는 것과 a%b를 하는 것은 같은 연산이고, 따라서 a%b를 하는 것이 훨씬 빠르기 때문이다. b가 0이 될 때 while문을 빠져나가는데, 이 때 a값이 우리가 구하고자 하는 최대공약수 이다. 수가 모두 소수라면 최대공약수는 1로 출력이 된다.
출처: https://fjvbn2003.tistory.com/37 [Chaos and Order]
내가 이해한대로 설명해 보자면
1. A와 B라는 수가 있다 (A>B) ex)A=144, B=108
2. A와 B를 최대공약수의 곱으로 나타낼 수 있다 (A=A1*q, B=B1*q)
144=4*36
108=3*36
3. A-B도 최대공약수를 포함한다
144-08=(4-3)*36 <-36의 배수로 나타내짐
4. A-B와 B의 최대공약수를 구하면 된다
B=108 A-B=144-108=(4-3)*36=36
108과 36의 최대공약수배수는 36이다
5. A=144, B=108의 최대공약수는 36이다.
즉, i=2부터 B까지 일일히 비교해서 최대공약수를 구하는 방식이아닌
A,B -> B, A-B로 반복하여 A-B가 0이될때 B값이 최대공약수라는 것을 알아낸다
그게 가능한 이유는 B와 A-B모두 최대공약수의 곱으로 나타낼 수 있기 때문이다
가끔 A=B가 B보다 큰 경우도 있고, 작은경우도 있는데 적절히 A자리에 큰값, B자리에 작은값이 오게 하면 된다
위에서는 108 36이 바로 36이 최대공약수라는 것을 알아냈지만 실제 프로그램은 이렇게 된다
A B (A>B, A-B와 B로 변환)
144 108
108 36
72 36
36 36
36 0
정답 36
보통 알고리즘을 짜면 뺄셈이아닌 %로하는데 그이유는
뺄셈보다 %이 더 중복된 횟수를 줄여주기때문이다
동일한 알고리즘이다
나의 코드
#include <iostream>
#include <math.h>
using namespace std;
int GCD(int, int);
int main() {
int n, d,temp,fgap,sgap=0;
cin >> n >> d;
for (int i = 0; i < n; i++) {
cin >> temp;
fgap = abs(temp - d);
sgap=GCD(fgap, sgap);
}
cout << sgap;
return 0;
}
int GCD(int a, int b) {
if (b == 0)
return a;
else {
return GCD(b, a % b);
}
}
'코딩 테스트 > 백준' 카테고리의 다른 글
백준 11279 최대 힙 c++ (0) | 2022.05.22 |
---|---|
백준 1744- 수 묶기 c++ (0) | 2022.03.21 |
백준 1931 회의실 배정 c++ (0) | 2022.02.20 |
백준 6588 c++ 골드바흐의 추측 (0) | 2022.02.16 |
퀵 정렬(Quick Sort) (0) | 2022.01.23 |
- Total
- Today
- Yesterday
- html
- oauth2.0
- 리눅스
- DDL
- 2024인프콘
- authorization code
- SQL
- SpringBoot
- git commit 수정
- oauth
- 오픈소스
- kloa
- 우분투
- authorization_code
- 인프콘2024
- git
- html #웹 #웹사이트 #플레이리스트
- 데이터3법
- 데이터 3법
- infcon 2024
- 프로그래머스
- 로스트아크 캐릭터
- CSS
- bfs
- DML
- 데이터베이스
- Android Studio
- 클로아
- javascript
- git 예전 커밋 수정
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |