ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

728x90

๐Ÿšฉ ์‹œ๋ฎฌ๋ ˆ์ด์…˜, ๊ตฌํ˜„, BFS

* 2021 ์‚ผ์„ฑ ์ƒ๋ฐ˜๊ธฐ ์˜ค์ „ ๊ณต์ฑ„ SW ์—ญ๋Ÿ‰ํ…Œ์ŠคํŠธ ๋ฌธ์ œ (SW Aํ˜•)

https://www.acmicpc.net/problem/21609

 

21609๋ฒˆ: ์ƒ์–ด ์ค‘ํ•™๊ต

์ƒ์–ด ์ค‘ํ•™๊ต์˜ ์ฝ”๋”ฉ ๋™์•„๋ฆฌ์—์„œ ๊ฒŒ์ž„์„ ๋งŒ๋“ค์—ˆ๋‹ค. ์ด ๊ฒŒ์ž„์€ ํฌ๊ธฐ๊ฐ€ N×N์ธ ๊ฒฉ์ž์—์„œ ์ง„ํ–‰๋˜๊ณ , ์ดˆ๊ธฐ์— ๊ฒฉ์ž์˜ ๋ชจ๋“  ์นธ์—๋Š” ๋ธ”๋ก์ด ํ•˜๋‚˜์”ฉ ๋“ค์–ด์žˆ๊ณ , ๋ธ”๋ก์€ ๊ฒ€์€์ƒ‰ ๋ธ”๋ก, ๋ฌด์ง€๊ฐœ ๋ธ”๋ก, ์ผ๋ฐ˜ ๋ธ”๋ก

www.acmicpc.net

 

 

thinking

1๏ธโƒฃ ์˜คํ† ํ”Œ๋ ˆ์ด -> while๋ฌธ ์‚ฌ์šฉ

2๏ธโƒฃ ํฌ๊ธฐ๊ฐ€ ๊ฐ€์žฅ ํฐ ๋ธ”๋ก ์ฐพ๊ธฐ -> ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก ๊ทธ๋ฃน์˜ ๊ฒฝ์šฐ๋ฅผ ๋ชจ๋‘ ๊ตฌํ•œ ํ›„, ๋‚ด๋ฆผ์ฐจ์ˆœ ์†ŒํŒ…ํ•ด์„œ ์ตœ๋Œ€๋ธ”๋ก ๊ตฌํ•˜๊ธฐ
     - ์ด๋•Œ, ๋ธ”๋กํฌ๊ธฐ, ๋ฌด์ง€๊ฐœํฌ๊ธฐ, ๋ธ”๋ก ์ขŒํ‘œ ํ•„์š”
     - ๋ฌด์ง€๊ฐœ ๋ธ”๋ก(0)์€ ์•„๋ž˜์ฒ˜๋Ÿผ ๋‹ค๋ฅธ ๋ธ”๋ก๊ณผ๋„ ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ๊ธฐ๋•Œ๋ฌธ์— ๋ฐฉ๋ฌธ์ฒดํฌ๋ฅผ ํ•ด์ œํ•ด์ค˜์•ผํ•œ๋‹ค.

3๏ธโƒฃ ๋ธ”๋ก์ œ๊ฑฐ+์ ์ˆ˜๋”ํ•˜๊ธฐ
     - 2๋ฒˆ์—์„œ ๊ตฌํ•œ ๋ธ”๋ก ์ขŒํ‘œ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ œ๊ฑฐ๋œ ๋ธ”๋ก๊ฐ’์„ -2 ๋กœ ์„ค์ •ํ•˜์—ฌ ๊ตฌ๋ถ„์ง€์–ด์คŒ

4๏ธโƒฃ ์ค‘๋ ฅ

5๏ธโƒฃ 90ํšŒ์ „

6๏ธโƒฃ ์ค‘๋ ฅ

 

๐Ÿ‘ป TIP ) 90๋„ ๋ฐ˜์‹œ๊ณ„ ํšŒ์ „์„ zip์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ

# a๋Š” array
a = list(zip(*a))[::-1]
a = [list(s) for s in a]

 

 

์ฝ”๋“œ

from collections import deque

# ์ธ์ ‘ ๋ธ”๋ก ์ฐพ๊ธฐ -> ๋ธ”๋ก ํฌ๊ธฐ, ๋ฌด์ง€๊ฐœํฌ๊ธฐ, ๋ธ”๋ก์ขŒํ‘œ ๋ฆฌํ„ด
def bfs(x, y, color):
    q = deque()
    q.append([x, y])
    dx = [-1, 0, 1, 0]
    dy = [0, 1, 0, -1]

    block_cnt, rainbow_cnt = 1, 0  # ๋ธ”๋ก๊ฐœ์ˆ˜, ๋ฌด์ง€๊ฐœ๋ธ”๋ก ๊ฐœ์ˆ˜
    blocks, rainbows = [[x,y]], []  # ๋ธ”๋ก์ขŒํ‘œ ๋„ฃ์„ ๋ฆฌ์ŠคํŠธ, ๋ฌด์ง€๊ฐœ์ขŒํ‘œ ๋„ฃ์„ ๋ฆฌ์ŠคํŠธ

    while q:
        x, y = q.popleft()
        for d in range(4):
            nx = x + dx[d]
            ny = y + dy[d]
            
            # ๋ฒ”์œ„ ์•ˆ์ด๋ฉด์„œ ๋ฐฉ๋ฌธ ์•ˆํ•œ ์ผ๋ฐ˜ ๋ธ”๋ก์ธ ๊ฒฝ์šฐ
            if 0 <= nx < N and 0 <= ny < N and not visited[nx][ny] and a[nx][ny] == color:
                visited[nx][ny] = 1
                q.append([nx, ny])
                block_cnt += 1
                blocks.append([nx, ny])
                
            # ๋ฒ”์œ„ ์•ˆ์ด๋ฉด์„œ ๋ฐฉ๋ฌธ ์•ˆํ•œ ๋ฌด์ง€๊ฐœ ๋ธ”๋ก์ธ ๊ฒฝ์šฐ
            elif 0 <= nx < N and 0 <= ny < N and not visited[nx][ny] and a[nx][ny] == 0:
                visited[nx][ny] = 1
                q.append([nx, ny])
                block_cnt += 1
                rainbow_cnt += 1
                rainbows.append([nx, ny])

    # ๋ฌด์ง€๊ฐœ๋ธ”๋ก์€ ๋ฐฉ๋ฌธ ๋‹ค์‹œ ํ•ด์ œ
    for x,y in rainbows:
        visited[x][y] = 0

    return [block_cnt, rainbow_cnt, blocks+rainbows]


# ๋ธ”๋ก ์ œ๊ฑฐ ํ•จ์ˆ˜
def remove(block):
    for x,y in block:
        a[x][y] = -2


# ์ค‘๋ ฅ ํ•จ์ˆ˜
def gravity(a):
    for i in range(N-2, -1, -1):  # ๋ฐ‘์—์„œ ๋ถ€ํ„ฐ ์ฒดํฌ
        for j in range(N):
            if a[i][j] > -1:  # -1์ด ์•„๋‹ˆ๋ฉด ์•„๋ž˜๋กœ ๋‹ค์šด
                r = i
                while True:
                    if 0<=r+1<N and a[r+1][j] == -2:  # ๋‹ค์Œํ–‰์ด ์ธ๋ฑ์Šค ๋ฒ”์œ„ ์•ˆ์ด๋ฉด์„œ -2์ด๋ฉด ์•„๋ž˜๋กœ ๋‹ค์šด
                        a[r+1][j] = a[r][j]
                        a[r][j] = -2
                        r += 1
                    else:
                        break


# ๋ฐ˜์‹œ๊ณ„ ํšŒ์ „ ํ•จ์ˆ˜
def rot90(a):
    new_a = [[0]*N for _ in range(N)]
    for i in range(N):
        for j in range(N):
            new_a[N-1-j][i] = a[i][j]
    return new_a



# 0. ๋ฉ”์ธ์ฝ”๋“œ
N, M = map(int, input().split())
a = [list(map(int, input().split())) for _ in range(N)]

score = 0  # ์ ์ˆ˜

# 1. ์˜คํ† ํ”Œ๋ ˆ์ด-> while {2. ํฌ๊ธฐ ๊ฐ€์žฅ ํฐ ๋ธ”๋ก ์ฐพ๊ธฐ 3. ๋ธ”๋ก์ œ๊ฑฐ+์ ์ˆ˜๋”ํ•˜๊ธฐ 4. ์ค‘๋ ฅ 5. 90ํšŒ์ „ 6. ์ค‘๋ ฅ}
while True:
    # 2. ํฌ๊ธฐ ๊ฐ€์žฅ ํฐ ๋ธ”๋ก ์ฐพ๊ธฐ
    visited = [[0] * N for _ in range(N)]  # ๋ฐฉ๋ฌธ์ฒดํฌ
    blocks = []  # ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก ๊ทธ๋ฃน๋“ค ๋„ฃ์„ ๋ฆฌ์ŠคํŠธ
    for i in range(N):
        for j in range(N):
            if a[i][j] > 0 and not visited[i][j]:  # ์ผ๋ฐ˜๋ธ”๋ก์ด๋ฉด์„œ ๋ฐฉ๋ฌธ ์•ˆํ–ˆ์œผ๋ฉด
                visited[i][j] = 1  # ๋ฐฉ๋ฌธ
                block_info = bfs(i, j, a[i][j])  # ์ธ์ ‘ํ•œ ๋ธ”๋ก ์ฐพ๊ธฐ
                # block_info = [๋ธ”๋กํฌ๊ธฐ, ๋ฌด์ง€๊ฐœ๋ธ”๋ก ๊ฐœ์ˆ˜, ๋ธ”๋ก์ขŒํ‘œ]
                if block_info[0] >= 2:
                    blocks.append(block_info)
    blocks.sort(reverse=True)

    # 3. ๋ธ”๋ก์ œ๊ฑฐ+์ ์ˆ˜๋”ํ•˜๊ธฐ
    if not blocks:
        break
    remove(blocks[0][2])
    score += blocks[0][0]**2

    # 4. ์ค‘๋ ฅ
    gravity(a)

    # 5. 90ํšŒ์ „
    a = rot90(a)

    # 6. ์ค‘๋ ฅ
    gravity(a)

print(score)
๋Œ“๊ธ€