Search

[Programmers] 퍼즐 조각 채우기

Tags
BFS
Date
2024/04/09

설명

테이블 위에 놓인 퍼즐 조각을 게임 보드의 빈 공간에 적절히 올려놓으려 합니다. 게임 보드와 테이블은 모두 각 칸이 1x1 크기인 정사각 격자 모양입니다. 이때, 다음 규칙에 따라 테이블 위에 놓인 퍼즐 조각을 게임 보드의 빈칸에 채우면 됩니다.
조각은 한 번에 하나씩 채워 넣습니다.
조각을 회전시킬 수 있습니다.
조각을 뒤집을 수는 없습니다.
게임 보드에 새로 채워 넣은 퍼즐 조각과 인접한 칸이 비어있으면 안 됩니다.
다음은 퍼즐 조각을 채우는 예시입니다.
위 그림에서 왼쪽은 현재 게임 보드의 상태를, 오른쪽은 테이블 위에 놓인 퍼즐 조각들을 나타냅니다. 테이블 위에 놓인 퍼즐 조각들 또한 마찬가지로 [상,하,좌,우]로 인접해 붙어있는 경우는 없으며, 흰 칸은 퍼즐이 놓이지 않은 빈 공간을 나타냅니다. 모든 퍼즐 조각은 격자 칸에 딱 맞게 놓여있으며, 격자 칸을 벗어나거나, 걸쳐 있는 등 잘못 놓인 경우는 없습니다.
이때, 아래 그림과 같이 3,4,5번 조각을 격자 칸에 놓으면 규칙에 어긋나므로 불가능한 경우입니다.
3번 조각을 놓고 4번 조각을 놓기 전에 위쪽으로 인접한 칸에 빈칸이 생깁니다.
5번 조각의 양 옆으로 인접한 칸에 빈칸이 생깁니다.
다음은 규칙에 맞게 최대한 많은 조각을 게임 보드에 채워 넣은 모습입니다.
최대한 많은 조각을 채워 넣으면 총 14칸을 채울 수 있습니다.
현재 게임 보드의 상태 game_board, 테이블 위에 놓인 퍼즐 조각의 상태 table이 매개변수로 주어집니다. 규칙에 맞게 최대한 많은 퍼즐 조각을 채워 넣을 경우, 총 몇 칸을 채울 수 있는지 return 하도록 solution 함수를 완성해주세요.

제한사항

3 ≤ game_board의 행 길이 ≤ 50
game_board의 각 열 길이 = game_board의 행 길이
즉, 게임 보드는 정사각 격자 모양입니다.
game_board의 모든 원소는 0 또는 1입니다.
0은 빈칸, 1은 이미 채워진 칸을 나타냅니다.
퍼즐 조각이 놓일 빈칸은 1 x 1 크기 정사각형이 최소 1개에서 최대 6개까지 연결된 형태로만 주어집니다.
table의 행 길이 = game_board의 행 길이
table의 각 열 길이 = table의 행 길이
즉, 테이블은 game_board와 같은 크기의 정사각 격자 모양입니다.
table의 모든 원소는 0 또는 1입니다.
0은 빈칸, 1은 조각이 놓인 칸을 나타냅니다.
퍼즐 조각은 1 x 1 크기 정사각형이 최소 1개에서 최대 6개까지 연결된 형태로만 주어집니다.
game_board에는 반드시 하나 이상의 빈칸이 있습니다.
table에는 반드시 하나 이상의 블록이 놓여 있습니다.

예시 입력

예시 출력

# game_board [[1,1,0,0,1,0], [0,0,1,0,1,0], [0,1,1,0,0,1], [1,1,0,1,1,1], [1,0,0,0,1,0], [0,1,1,1,0,0]] # table [[1,0,0,1,1,0], [1,0,1,0,1,0], [0,1,1,0,1,1], [0,0,1,0,0,0], [1,1,0,1,1,0], [0,1,0,0,0,0]]
JavaScript
복사
14
JavaScript
복사

풀이 과정

문제를 한 줄로 요약하면 다음과 같습니다.
빈 칸이 최대한 남지 않도록 빈 공간에 퍼즐을 끼워 맞춰라
그렇다면 어떻게 최적의 결과로 퍼즐을 끼워 맞출 수 있을까요? 문제는 간단합니다.
빈 공간과 퍼즐의 모양을 좌표로 기록합니다.
비교를 위해서 두 좌표 모두 (0,0)을 기준으로 기록합니다.
빈 공간과 퍼즐 모두 내림 차순 정렬 후 하나 씩 비교 합니다.
이 때, 90도로 4번 (즉, 360도 회전) 하여 빈 공간의 모양과 퍼즐의 모양이 일치하는지 확인합니다.
만약 일치 혹은 빈 공간 안에 퍼즐이 들어간다면 남은 공간을 제외한 블럭 수를 기록합니다.
예를 들어, 5칸 짜리 빈 공간에 4칸 짜리 퍼즐이 들어간다면 4칸을 채울 수 있다고 기록

최종 코드

JavaScript
복사

Reference