문제 링크

풀이 과정

구현 팁

전체 코드

from collections import deque

def isin_boundary(cur_row, cur_col, rows, cols):
    row_cond = (cur_row >= 0 and cur_row < rows)
    col_cond = (cur_col >= 0 and cur_col < cols)
    return row_cond & col_cond

def find_blocks(board, mode):
    # mode: 0 -> table / mode: 1 -> game_board
    row_len, col_len = len(board), len(board[0])
    visited_list = [[0 for _ in range(col_len)] for _ in range(row_len)]
    deltas = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    blocks = list()
     
    for row in range(row_len):
        for col in range(col_len):
            if (board[row][col] ^ mode == 1) and (visited_list[row][col] == 0):
                block_temp = [(row, col)]
                visited_list[row][col] = 1
                queue = deque([(row, col)])
                
                while queue:  # BFS
                    cur_row, cur_col = queue.popleft()
                    for dy, dx in deltas:
                        nrow, ncol = cur_row + dy, cur_col + dx
                        if isin_boundary(nrow, ncol, row_len, col_len):
                            if (visited_list[nrow][ncol] == 0) and (board[nrow][ncol] ^ mode == 1):
                                visited_list[nrow][ncol] = 1
                                block_temp.append((nrow, ncol))
                                queue.append((nrow, ncol))
                
                blocks.append(block_temp)
    return blocks

def make_rectangle(blocks):
    rows, cols = zip(*blocks)
    row_max, row_min = max(rows), min(rows)
    col_max, col_min = max(cols), min(cols)
    row_len = row_max - row_min + 1
    col_len = col_max - col_min + 1
    rectangle = [[0 for _ in range(col_len)] for _ in range(row_len)]
    
    for row, col in blocks:
        rectangle[row-row_min][col-col_min] = 1 
        
    return rectangle

def rotate(rectangle):  # 90도 회전
    row_len, col_len = len(rectangle), len(rectangle[0])
    result = [[0 for _ in range(row_len)] for _ in range(col_len)]
    blocks = 0
    for row in range(row_len):
        for col in range(col_len):
            if rectangle[row][col] == 1:    blocks += 1
            result[col][row_len-1-row] = rectangle[row][col]
    return (result, blocks)
    
def solution(game_board, table):
    answer = 0
    game_board_blocks = find_blocks(game_board, 1)
    table_blocks = find_blocks(table, 0)
    
    for game_board_block in game_board_blocks:
        find_flag = False
        game_rectangle = make_rectangle(game_board_block)
        
        for table_block in table_blocks:
            if find_flag:   break  
            table_rantangle = make_rectangle(table_block)
            
            for _ in range(4):   # 최대 360도 회전
                game_rectangle, blocks = rotate(game_rectangle)
                if game_rectangle == table_rantangle:
                    find_flag = True
                    answer += blocks
                    table_blocks.remove(table_block)
                    break
                    
    return answer

유사 문제