Judge

Programmers - 멀쩡한 사각형

깡구_ 2022. 6. 28. 10:59

title: Programmers - 멀쩡한 사각형
date: 2022-06-28
tags:

  • Algorithm




https://programmers.co.kr/learn/courses/30/lessons/62048


문제 요약

1억 이하의 정수인 w와 h로 이루어진 사각형이 존재한다. 1 단위 격자로 나뉘어 있으며, 한 꼭지점과 대각선 꼭지점을 잇는 선분에 맞추어 자르면 잘린 정사각형은 사용할 수 없다. 사용 가능한 남은 부분의 개수를 return한다.


문제 풀이

w와 h 각각 1억 이하이며, 서로소 혹은 소수로 인해 작은 사각형으로 분리할 수 없는 상황이 생긴다. 이로 인해 O(n)밖에 노릴 수 없다.
기울기에 맞추어 어느 정사각형이 잘리는지 count한다.
만약 작은 격자의 꼭지점을 지나면 w와 h의 최대공약수가 1이 아니라는 뜻이며, 현재 구하고 있는 사각형의 크기로 w와 h로 이루어진 사각형을 나눌 수 있다는 소리다. 그때까지 구한 잘린 정사각형의 수를 간단한 연산과 함께 처리해주면 1억개를 전부 셀 필요 없이 정답을 찾을 수 있다.

이렇게 수학과 관련된 큰 반복이 필요한 문제는 일반화를 시키는 것이 가장 중요하다. 문제를 풀고 다른 풀이를 확인하고 나서야 일반화를 시킬 수 있었다.
선분이 격자들의 경계(꼭지점)을 지나지 않을 경우, 잘리는 정사각형은 w + h - 1 이다.
꼭지점을 지날 때마다 해당 일반화 식에서 1씩 빼야 하며, 이는 결국 최대공약수와 관계가 있음을 알 수 있다.
결국 잘린 정사각형의 개수는 w + h - w와 h의 최대공약수 이다.


프로그램

long long solution ( int w ,int h )
{
    long long answer = 0 ;
    int iFormer = 0 ;
    int iCurret = 0 ;
    double dTemp = 0 ;



    for ( int i = 1 ; i <= w ; ++i )
    {
        iCurret = dTemp = ( long long ) h * i / ( double ) w ;

        if ( iCurret == dTemp )                    // Find small rectangle to split
        {
            answer += iCurret - iFormer ;

            answer *= w / i ;

            break ;
        }

        ++ iCurret ;
        answer += iCurret - iFormer ;
        iFormer = iCurret - 1 ;
    }

    return ( long long ) w * h - answer ;
}