▼ 문제 링크
코딩테스트 연습 - 멀쩡한 사각형
가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를 격자 선을
programmers.co.kr
풀이 1, 2 할 거 없이 처음부터 테스트 케이스를 전부 다 만족하지 못해서 결국 눈물을 꾹 참으면서 어린 시절 구몬 학습지 맨 뒷장 펼쳐서 답안지 베끼던 실력으로 구글링했다.
그치만 뭐... 다 이러면서 크는 거지
출처: https://leedakyeong.tistory.com/entry/프로그래머스-멀쩡한-사각형-in-python [슈퍼짱짱]
# 풀이
최대공약수와 유클리드 호제법
import Foundation
func solution(_ w: Int, _ h: Int) -> Int64 {
let answer: Int64 = Int64(w * h)
let gcd = getGcd(w, h)
return answer - Int64(w + h - gcd)
}
// 최대공약수 구하기 - 유클리드 호제법
func getGcd(_ num1: Int, _ num2: Int) -> Int {
guard num1 != 0 && num2 != 0 else {
return 0
}
guard num1 != 1 && num2 != 1 else {
return 1
}
guard num1 % num2 != 0 else {
return num2
}
guard num2 % num1 != 0 else {
return num1
}
var big = (num1 > num2 ? num1 : num2)
var small = (num1 < num2 ? num1 : num2)
while big % small != 0 {
let temp = big % small
big = small
small = temp
}
return small
}
처음에는 최대공약수랑 무슨 상관이지 싶었는데, 자세히 보니 특정한 패턴이 최대공약수만큼 반복하고 있었다.
문제에 주어진 예시인 (8x12)를 살펴봐도 기울기 그래프를 따라 (2x3)칸이 4번 반복되는 것을 확인할 수 있다.
대각선을 가로지르는 선과 연관된 사각형 반복 패턴
(가로 / 최대공약수) x (세로 / 최대공약수) * 최대공약수
반복되는 패턴을 떼어 일부만 확대해보면 위와 같다. 이때, 대각선에 직접적으로 영향을 받는 정사각형의 개수는 (패턴의 가로 + 패턴의 세로 - 1) 이다. (이때 가로, 세로는 종이 전체가 아니라 확대하여 잘라낸 패턴의 가로, 세로)
이런 패턴이 최대공약수 만큼 반복되므로, 결과적으로 (가로 + 세로 - 최대공약수)가 된다. (이때 가로, 세로는 전체 종이의 가로, 세로)
# 최대공약수 구하는 법
유클리드 호제법에 대하여…
위키피디아에서 설명하는 유클리드 호제법은 다음과 같다.
2개의 자연수(또는 정식) a, b에 대해서 a를 b로 나눈 나머지를 r이라 하면(단, a>b), a와 b의 최대공약수는 b와 r의 최대공약수와 같다. 이 성질에 따라, b를 r로 나눈 나머지 r'를 구하고, 다시 r을 r'로 나눈 나머지를 구하는 과정을 반복하여 나머지가 0이 되었을 때 나누는 수가 a와 b의 최대공약수이다.
➡️ 큰 수를 작은 수로 나눈 나머지값으로 다시 작은 수를 나누는 과정을 나머지가 0이 될 때까지 반복한다. 마지막(나머지가 0이 될 때)에 사용된 "작은 수"가 두 수의 최대공약수이다.
유클리드 호제법으로 48과 18의 최대공약수를 구하는 과정을 살펴보면 다음과 같다.
48 % 18 = 12
18 % 12 = 6
12 % 6 = 0
➡️ 마지막 계산식의 6이 48과 18의 최대공약수가 됨
코드로 나타내면 다음과 같다.
while big % small != 0 {
let temp = big % small
big = small
small = temp
}
위 반복문 과정을 통해 가장 마지막 small값이 최대공약수가 된다.
'Algorithm' 카테고리의 다른 글
[코딜리티] CountNonDivisible (0) | 2021.08.12 |
---|---|
[리트코드] Remove All Adjacent Duplicates in String II (0) | 2021.08.07 |
[코딜리티] MaxDoubleSliceSum (0) | 2021.07.23 |
[프로그래머스] 정렬 - 가장 큰 수 (0) | 2021.07.11 |
[코딜리티] Stone Wall - Stack과 Queue (0) | 2021.07.01 |