최대공약수(gcd)를 쉽게 구할 수 있게 해주는 공식.
숫자 a와 b가 주어진다고 했을때 두수의 최대 공약수 gcd(a,b)를 구하는 문제를 생각해보자.
a>b 라고 했을 때 $a = bq+r$ 꼴로 표현할 수 있는데,
$gcd(a, b) = gcd(b, r) $
이란것이 유클리드 호제법이다.
r = a%b는 b보다 작으므로 gcd(a,b)에서 gcd(b,r)로 순서가 바뀜에 주의하자.
(사실 gcd는 순서에 무관하나 이해를 위해 a>b라는 속성을 유지하는 것)
증명은 여기를 참고하자.
계속 위처럼 하다가 r==0이 되는 순간 즉 a가 b로 나눠떨어지는 순간 b를 리턴하면 된다.
위의 내용대로 구현한 코드는 다음과 같다.
int gcd(int a, int b)
{
while(1)
{
int r = a%b;
if(r==0) return b;
a=b,b=r;
}
}
그런데 위의 코드는 함수 종료부분에 return 코드도 없고 while(1)인것도 좀 그래서 살짝 정리하고 나면 인터넷에 많이 퍼져있는 다음 형태가 된다.(자료형도 좀 더 사용성 좋도록 long long으로 변경)
long long gcd(long long a, long long b) {
while (b > 0)
{
long long t = a % b;
a = b, b = t;
}
return a;
}
재귀호출 버전
1
2
3
4
|
long long gcd(long long a, long long b) {
return (b == 0) ? a : gcd(b, a%b);
}
|
cs |
여러수의 최대공약수 구하기
n개의 숫자에 대한 최대 공약수를 구할때는 단순히 루프를 돌면서 gcd를 반복하면 된다.
마치 max함수가 n개에 대해서 할때는 여러번 적용하듯이..
관련문제
http://codeup.kr/problem.php?id=4016
내 풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
int gcd(int a, int b)
{
int c;
while (b) {
c = a % b;
a = b, b = c;
}
return a;
}
int main(void)
{
int n = 3;
int* d = new int[n + 1](); for (int i = 0; i < n; i++) scanf("%d", d + i);
int v = gcd(d[0], d[1]);
for (int i = 2; i < n; i++) v = gcd(v, d[i]);
printf("%d\n", v);
return 0;
}
|
cs |
반응형
'Programming > Algorithm' 카테고리의 다른 글
약수 출력하기 (0) | 2019.03.24 |
---|---|
우선순위 큐(priority queue) (0) | 2019.03.24 |
LCS(longest common sequence, 최장공통부분수열) (0) | 2019.03.19 |
이항계수( binomial coefficient), 조합(combination) (0) | 2019.03.14 |
[algorithm] subset sum (0) | 2017.11.20 |