/////
Search
Duplicate

멀쩡한 사각형

태그
기타
비고
체크 필요

문제

가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를 격자 선을 따라 1cm × 1cm의 정사각형으로 잘라 사용할 예정이었는데, 누군가가 이 종이를 대각선 꼭지점 2개를 잇는 방향으로 잘라 놓았습니다. 그러므로 현재 직사각형 종이는 크기가 같은 직각삼각형 2개로 나누어진 상태입니다. 새로운 종이를 구할 수 없는 상태이기 때문에, 이 종이에서 원래 종이의 가로, 세로 방향과 평행하게 1cm × 1cm로 잘라 사용할 수 있는 만큼만 사용하기로 하였습니다.
가로의 길이 W와 세로의 길이 H가 주어질 때, 사용할 수 있는 정사각형의 개수를 구하는 solution 함수를 완성해 주세요.

제한사항

• W, H : 1억 이하의 자연수

예시

가로가 8, 세로가 12인 직사각형을 대각선 방향으로 자르면 총 16개 정사각형을 사용할 수 없게 됩니다. 원래 직사각형에서는 96개의 정사각형을 만들 수 있었으므로, 96 - 16 = 80 을 반환합니다.

정답

# 최대 공약수 구하는 함수 def gcd_f(a,b): while b != 0: # 나머지가 0이 될 때까지 반복 a, b = b, a%b return a def solution(w,h): gcd = gcd_f(w,h) # 최대공약수 not_use = w+h-gcd # 못 쓰는 사각형 ((w/gcd + h/gcd-1)*gcd) answer = w*h-not_use # 전체 사각형 - 못 쓰는 사각형 return answer
Python
복사

풀이

우선 예시를 살펴보면 못 쓰는 사각형의 형태가 4개 반복된다는 것을 확인할 수 있다.
이는 양변의 길이가 8:12인데 2:3을 각각 4배씩 확장한 형태이기 때문이다. 다시 말해서 총 못 쓰는 사각형의 개수는 양변의 길이를 각각 최대 공약수로 나눴을 때 나오는 사각형에서 나오는 못 쓰는 사각형에 최대 공약수를 곱하면 된다. 수식으로 보면 이해가 될 것.
총 못 쓰는 사각형의 개수 = 최대공약수로 나눈 사각형의 못 쓰는 사각형 * 최대 공약수
Python
복사
따라서 가장 먼저 필요한 것은 최대 공약수를 구하는 함수이다.
최대 공약수를 구하는 함수에 대한 설명은 링크 참조 최대 공약수, 최소 공배수
# 최대 공약수 구하는 함수 def gcd_f(a,b): while b != 0: # 나머지가 0이 될 때까지 반복 a, b = b, a%b return a
Python
복사
그 다음 구해야 하는 것은 최대 공약수로 나눈 사각형의 못 쓰는 사각형의 개수이다.
못 쓰는 사각형의 개수는 대각선이 지나가는 사각형의 개수와 동일하다. 그러면 대각선이 왼쪽 위에서 오른쪽 아래로 갈 때까지 지나가는 데에 필요한 사각형의 개수를 구할 수 있으면 된다.
왼쪽 위에서 오른쪽 아래로 가려면 (세로 길이 + 가로 길이 - 1) 만큼 칸을 지나가야 한다.
예시의 사각형을 살펴보자. (최대 공약수로 나눈 사각형)
왼쪽 끝에서 오른쪽 끝으로 가기 때문에 무조건 가로 개수만큼은 건너가야 한다.
그리고 맨 위에서 맨 아래로 가기 때문에 무조건 세로 개수만큼은 건너가야 한다.
그리고 겹치는 구간이 있기 때문에 1을 빼주어야 한다.
따라서 예시에서 못 쓰는 사각형의 총 개수를 구해보면
우선 8과 12의 최대 공약수는 4이다. 그러면 각 변의 길이를 최대 공약수로 나누면 2:3이고 2:3의 사각형에서 못 쓰는 사각형의 개수는 (2+3-1) = 4이다. 그리고 최대 공약수를 곱하면 16이다.
이를 함수로 정리하면 다음과 같다.
def solution(w,h): gcd = gcd_f(w,h) # 최대공약수 not_use = w+h-gcd # 못 쓰는 사각형 ((w/gcd + h/gcd-1)*gcd) answer = w*h-not_use # 전체 사각형 - 못 쓰는 사각형 return answer
Python
복사