๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
โญ Problem_Solving/ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค] ํผ์ฆ ์กฐ๊ฐ ์ฑ„์šฐ๊ธฐ (Python/ํŒŒ์ด์ฌ)

by ํฌ์ŠคํŠธ์‰์ดํฌ 2023. 2. 11.

<๋ฌธ์ œ ๋งํฌ>

https://school.programmers.co.kr/learn/courses/30/lessons/84021

 

ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

programmers.co.kr

 

<ํ’€์ด ์ „๋žต>

1. ํ’€์ด ์ „๋žต์€ ํฌ๊ฒŒ 1. ๋ธ”๋Ÿญ ๋ชจ์–‘๊ณผ ๋นˆ๊ณต๊ฐ„์„ ์ถ”์ถœํ•ด์„œ + 2. ๋‘˜์„ ๋น„๊ตํ•œ๋‹ค ๋‘ ๊ณผ์ •์ด๋‹ค.

2. ๋ธ”๋Ÿญ ๋ชจ์–‘๊ณผ ๋นˆ๊ณต๊ฐ„ ์ถ”์ถœ์€ bfs๋กœ ์ถ”์ถœํ•ด์„œ ๋ชจ์–‘์˜ ์ธ๋ฑ์Šค๋ฅผ ์ €์žฅํ•œ๋‹ค.

3. ๋‘˜ ๊ฐ„์˜ ๋น„๊ต๊ฐ€ ์–ด๋ ค์šด๋ฐ ๋‚˜๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ๋‘˜ ๊ฐ„์˜ 1:1 ๋งค์นญ์„ ์œ„ํ•ด ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€์žฅ ์ž‘์€ ์ขŒํ‘œ๋ฅผ ๋บด์คŒ์œผ๋กœ์„œ (0, 0)๊ธฐ์ค€์œผ๋กœ ์žฌ๋น„์น˜ํ•˜๊ณ , ์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ 90, 180, 270๋„ ํšŒ์ „ํ•ด๊ฐ€๋ฉด์„œ ์ตœ์†Ÿ๊ฐ’๋งŒ์„ ์ €์žฅํ•ด ๋ชจ์–‘๋“ค์„ normalize ์‹œ์ผœ์คฌ๋‹ค.

4. ๋งˆ์ง€๋ง‰์œผ๋กœ ์ค‘๋ณต ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜๋ฉด์„œ normalizeํ•œ ๋ชจ์–‘๋“ค์„ ๋น„๊ตํ•ด๊ฐ€๋ฉด์„œ ์„ธ์ฃผ์—ˆ๋‹ค

5. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ๊ณ ๋“์  kit ๋ฌธ์ œ ์ค‘์— ๊ฐ€์žฅ ๊ผผ๊ผผํ•œ ๊ตฌํ˜„์ด ์š”๊ตฌ๋˜์—ˆ๋˜ ๋ฌธ์ œ. ์ด๋Ÿฐ ๋ฌธ์ œ๋“ค์„ ์ฃผ์š” ์ฝ”๋“œ ๋ธ”๋Ÿญ์„ ํ•จ์ˆ˜ ๋“ฑ์„ ํ†ตํ•ด ๋ชจ๋“ˆํ™” ํ•˜๊ณ  ์ค‘๊ฐ„์ค‘๊ฐ„ ์ฃผ์„์„ ๋‹ฌ๋ฉด์„œ ํ‘ธ๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋œ๋‹ค.

 

<์ •๋‹ต ์ฝ”๋“œ>

# 210122 ํผ์ฆ์กฐ๊ฐ์ฑ„์šฐ๊ธฐ


from collections import deque


dr = [-1, 1, 0, 0]
dc = [0, 0, -1, 1]


def bfs(board, r, c, visited, target, N):
    '''
    board: ๋ฐฐ์—ด ์ข…๋ฅ˜ (๊ฒŒ์ž„ / ํ…Œ์ด๋ธ”)
    r, c: ์ขŒํ‘œ
    visited: ํ•ด๋‹น ๋ฐฐ์—ด์˜ ๋ฐฉ๋ฌธ ํ‘œ์‹œ ๋ฐฐ์—ด
    target: ํ•ด๋‹น ๋ฐฐ์—ด์—์„œ ์ฐพ๊ณ ์ž ํ•˜๋Š” ์ˆซ์ž
    N: ๋ฐฐ์—ด ํฌ๊ธฐ
    '''

    # result: ๋ธ”๋Ÿญ ์ขŒํ‘œ ๋‹ด์„ ๋ฐฐ์—ด
    result = [(r, c)]
    visited[r][c] = 1

    queue = deque()
    queue.append((r, c))
    
    # bfs ํƒ์ƒ‰์œผ๋กœ ๋ธ”๋Ÿญ ์ขŒํ‘œ๋“ค ์ฐพ์•„์„œ ๋ฐ˜ํ™˜
    while queue:

        r, c = queue.popleft()

        for i in range(4):

            nr = r + dr[i]
            nc = c + dc[i]

            if 0 <= nr < N and 0 <= nc < N:
                if not visited[nr][nc] and board[nr][nc] == target:

                    queue.append((nr, nc))
                    visited[nr][nc] = 1

                    result.append((nr, nc))
    
    return result


# ๋ธ”๋Ÿญ ์ •๋ ฌ ํ›„ ์žฌ๋ฐฐ์น˜
def sort_block(block: list):

    # ์ •๋ ฌ
    block.sort()

    min_r = min([b[0] for b in block])
    min_c = min([b[1] for b in block])

    # ๋ธ”๋Ÿญ ๊ฐ„ ๋น„๊ต ์œ„ํ•ด ๊ฐ€์žฅ ์ž‘์€ ์ขŒํ‘œ ๊ธฐ์ค€์œผ๋กœ ์žฌ๋ฐฐ์น˜
    block = list(map(lambda x: (x[0] - min_r, x[1] - min_c), block))

    return block


# ๋ธ”๋Ÿญ ํšŒ์ „
def rotate_block(block: list, N):

    # ํ•œ ์กฐ๊ฐ ๋ธ”๋Ÿญ์€ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜
    if len(block) == 1:
        return block

    # blocks: ํšŒ์ „๋œ ๋ธ”๋Ÿญ๋“ค์„ ๋‹ด์„ ๋ฐฐ์—ด
    blocks = [block]

    # 90, 180, 270๋„ ํšŒ์ „+์ •๋ ฌ 
    for i in range(3):
        block = list(map(lambda x: (x[1], N - 1 - x[0]), block))

        block = sort_block(block)
        blocks.append(block)

    # ๋ธ”๋Ÿญ ๊ฐ„ ๋น„๊ต ์œ„ํ•ด ๊ฐ€์žฅ ์ž‘์€ ์ขŒํ‘œ์˜ ๋ธ”๋Ÿญ ํ•œ ๊ฐœ๋งŒ ๋ฐ˜ํ™˜
    return min(blocks)



def solution(game_board, table):

    # ๋ณ€์ˆ˜ ์„ค์ • ๋ฐ ์ดˆ๊ธฐํ™”
    answer = 0

    N = len(game_board)

    # ๋ฐฉ๋ฌธ ์—ฌ๋ถ€ ํ‘œ์‹œ ๋ฐฐ์—ด
    visited_board = [[0 for _ in range(N)] for _ in range(N)]
    visited_table = [[0 for _ in range(N)] for _ in range(N)]
    
    # ๋ธ”๋Ÿญ ๋‹ด์„ ๋ฐฐ์—ด
    block_board = []
    block_table = []

    for r in range(N):
        for c in range(N):

            # board
            if not visited_board[r][c] and game_board[r][c] == 0:

                block = bfs(game_board, r, c, visited_board, 0, N) # ๋ธ”๋Ÿญ ํƒ์ƒ‰
                block = sort_block(block) # ์ •๋ ฌ ํ›„ ์žฌ๋ฐฐ์น˜
                block = rotate_block(block, N) # ํšŒ์ „

                block_board.append(block)
            
            # table
            if not visited_table[r][c] and table[r][c] == 1:

                block = bfs(table, r, c, visited_table, 1, N)
                block = sort_block(block)
                block = rotate_block(block, N)

                block_table.append(sort_block(block))

    # ํผ์ฆ ์กฐ๊ฐ ์ฑ„์šธ ๋•Œ ์ค‘๋ณต ์—ฌ๋ถ€ ๊ฒ€์‚ฌ์šฉ ๋ฐฐ์—ด
    checked_board = [0 for _ in range(len(block_board))]


    for block in block_table:
        for i in range(len(block_board)):
            
            # ์ด๋ฏธ ์ฑ„์› ์„ ๊ฒฝ์šฐ
            if checked_board[i]:
                continue
            
            # ์ฑ„์šธ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ
            if block == block_board[i]:
                checked_board[i] = 1
                answer += len(block)                
                break
                    
    return answer

๋Œ“๊ธ€