😎 κ³΅λΆ€ν•˜λŠ” μ§•μ§•μ•ŒνŒŒμΉ΄λŠ” μ²˜μŒμ΄μ§€?

[BAEKJOON python] 21609_상어 쀑학ꡐ λ³Έλ¬Έ

πŸ¦₯ μ½”ν…Œ/BAEKJOON

[BAEKJOON python] 21609_상어 쀑학ꡐ

μ§•μ§•μ•ŒνŒŒμΉ΄ 2023. 4. 8. 23:08
728x90
λ°˜μ‘ν˜•
상어 μ€‘학ꡐ
상어 μ€‘ν•™κ΅μ˜ μ½”λ”© λ™μ•„λ¦¬μ—μ„œ κ²Œμž„을 λ§Œλ“€μ—ˆλ‹€
이 κ²Œμž„은 ν¬κΈ°κ°€ N×N인 κ²©μžμ—μ„œ μ§„ν–‰λ˜κ³ , μ΄ˆκΈ°μ— κ²©μžμ˜ λͺ¨λ“  μΉΈμ—λŠ” λΈ”둝이 ν•˜λ‚˜μ”© λ“€μ–΄μžˆμŒ
    λΈ”둝은 κ²€μ€μƒ‰ λΈ”둝, λ¬΄μ§€κ°œ λΈ”둝, μΌλ°˜ λΈ”둝
    μΌλ°˜ λΈ”둝은 Mκ°€μ§€ μƒ‰μƒμ΄ μžˆκ³ , μƒ‰μ€ Mμ΄ν•˜μ˜ μžμ—°μˆ˜λ‘œ ν‘œν˜„
    κ²€μ€μƒ‰ λΈ”둝은 -1
    λ¬΄μ§€κ°œ λΈ”둝은 0으둜 ν‘œν˜„
(i, j)λŠ” κ²©μžμ˜ i번 ν–‰, j번 μ—΄μ„ μ˜λ―Έ
|r1 - r2| + |c1 - c2| = 1을 λ§Œμ‘±ν•˜λŠ” λ‘ μΉΈ (r1, c1)κ³Ό (r2, c2)λ₯Ό μΈμ ‘ν•œ μΉΈ

블둝 κ·Έλ£Ήμ€ μ—°κ²°λœ λΈ”λ‘μ˜ μ§‘ν•©
일반 λΈ”둝이 μ μ–΄λ„ ν•˜λ‚˜ μžˆμ–΄μ•Ό ν•˜λ©°, μΌλ°˜ λΈ”λ‘μ˜ μƒ‰μ€ λͺ¨λ‘ κ°™μ•„μ•Ό ν•œλ‹€
검은색 λΈ”둝은 ν¬ν•¨λ˜λ©΄ μ•ˆ λ˜κ³ , λ¬΄μ§€κ°œ λΈ”둝은 μ–Όλ§ˆλ‚˜ λ“€μ–΄μžˆλ“  μƒκ΄€μ—†λ‹€
그룹에 μ†ν•œ λΈ”λ‘μ˜ κ°œμˆ˜λŠ” 2보닀 ν¬κ±°λ‚˜ κ°™μ•„μ•Ό ν•˜λ©°, μž„μ˜μ˜ ν•œ λΈ”λ‘μ—μ„œ κ·Έλ£Ήμ— μ†ν•œ μΈμ ‘ν•œ μΉΈμœΌλ‘œ μ΄λ™ν•΄μ„œ κ·Έλ£Ήμ— μ†ν•œ λ‹€λ₯Έ λͺ¨λ“  μΉΈμœΌλ‘œ μ΄λ™ν•  μˆ˜ μžˆμ–΄μ•Ό ν•œλ‹€
블둝 κ·Έλ£Ήμ˜ κΈ°μ€€ λΈ”둝은 λ¬΄μ§€κ°œ λΈ”둝이 μ•„λ‹Œ λΈ”둝 μ€‘μ—μ„œ ν–‰μ˜ λ²ˆν˜Έκ°€ κ°€μž₯ μž‘은 λΈ”둝, κ·ΈλŸ¬ν•œ λΈ”둝이 μ—¬λŸ¬κ°œλ©΄ μ—΄μ˜ λ²ˆν˜Έκ°€ κ°€μž₯ μž‘은 λΈ”둝

μ˜€λŠ˜μ€ μ΄ κ²Œμž„에 μ˜€ν†  ν”Œλ ˆμ΄ κΈ°λŠ₯을 λ§Œλ“œλ €κ³  ν•œλ‹€
μ˜€ν†  ν”Œλ ˆμ΄λŠ” λ‹€μŒκ³Ό κ°™μ€ κ³Όμ •이 λΈ”둝 κ·Έλ£Ήμ΄ μ‘΄μž¬ν•˜λŠ” λ™μ•ˆ κ³„μ†ν•΄μ„œ λ°˜λ³΅
1) ν¬κΈ°κ°€ κ°€μž₯ ν° λΈ”둝 κ·Έλ£Ήμ„ μ°ΎλŠ”λ‹€
    λΈ”둝 κ·Έλ£Ήμ΄ μ—¬λŸ¬ κ°œλΌλ©΄ ν¬ν•¨λœ λ¬΄μ§€κ°œ λΈ”λ‘μ˜ μˆ˜κ°€ κ°€μž₯ λ§Žμ€ λΈ”둝 κ·Έλ£Ή
    κ·ΈλŸ¬ν•œ λΈ”둝도 μ—¬λŸ¬κ°œλΌλ©΄ κΈ°μ€€ λΈ”λ‘μ˜ ν–‰μ΄ κ°€μž₯ ν° κ²ƒμ„
    κ·Έ κ²ƒλ„ μ—¬λŸ¬κ°œμ΄λ©΄ μ—΄μ΄ κ°€μž₯ ν° κ²ƒμ„ μ°ΎλŠ”λ‹€
2) 1) μ—μ„œ μ°Ύμ€ λΈ”둝 κ·Έλ£Ήμ˜ λͺ¨λ“  λΈ”둝을 μ œκ±°ν•œλ‹€
    λΈ”둝 κ·Έλ£Ήμ— ν¬ν•¨λœ λΈ”λ‘μ˜ μˆ˜λ₯Ό B라고 ν–ˆμ„ λ•Œ, B^2점을 νšλ“
3) κ²©μžμ— μ€‘λ ₯이 μž‘μš©ν•œλ‹€
4) κ²©μžκ°€ 90도 λ°˜μ‹œκ³„ λ°©ν–₯으둜 νšŒμ „
5) λ‹€μ‹œ κ²©μžμ— μ€‘λ ₯이 μž‘μš©
    κ²©μžμ— μ€‘λ ₯이 μž‘μš©ν•˜λ©΄ κ²€μ€μƒ‰ λΈ”둝을 μ œμ™Έν•œ λͺ¨λ“  λΈ”둝이 ν–‰μ˜ λ²ˆν˜Έκ°€ ν° μΉΈμœΌλ‘œ μ΄λ™
    μ΄λ™μ€ λ‹€λ₯Έ λΈ”λ‘μ΄λ‚˜ κ²©μžμ˜ κ²½κ³„λ₯Ό λ§Œλ‚˜κΈ° μ „κΉŒμ§€ κ³„속 λœλ‹€

μ˜€ν†  ν”Œλ ˆμ΄κ°€ λͺ¨λ‘ λλ‚¬μ„ λ•Œ νšλ“ν•œ μ μˆ˜μ˜ ν•©μ„ κ΅¬ν•΄λ³΄μž

첫째 μ€„에 κ²©μž ν•œ λ³€μ˜ ν¬κΈ° N, μƒ‰μƒμ˜ κ°œμˆ˜ M
λ‘˜μ§Έ μ€„λΆ€ν„° N개의 μ€„에 κ²©μžμ˜ μΉΈμ— λ“€μ–΄μžˆλŠ” λΈ”λ‘μ˜ μ •보가 1번 ν–‰λΆ€ν„° N번 ν–‰
    κ° ν–‰μ— λŒ€ν•œ μ •λ³΄λŠ” 1μ—΄λΆ€ν„° Nμ—΄κΉŒμ§€
    μΉΈμ˜ μ •λ³΄λŠ” -1, 0, Mμ΄ν•˜
from collections import deque

# 격자 ν•œ λ³€μ˜ 크기 N, μƒ‰μƒμ˜ 개수 M
n, m = map(int, input().split())
# 격자의 칸에 λ“€μ–΄μžˆλŠ” λΈ”λ‘μ˜ 정보 (검은색 블둝, λ¬΄μ§€κ°œ 블둝, 일반 블둝은 Mκ°€μ§€ 색상)
board = [list(map(int, input().split())) for _ in range(n)]

# λ°˜μ‹œκ³„ λ°©ν–₯
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]


def bfs(x, y, visited, b_num):
    queue = deque()
    queue.append((x, y))
    # 블둝 정보
    c = board[x][y]
    # 일반 블둝은 Mκ°€μ§€ 색상, 검은색 블둝은 -1, λ¬΄μ§€κ°œ 블둝은 0
    # 방문처리 + 블둝 κ·Έλ£Ή 번호 μ €μž₯
    visited[x][y] = b_num
    size, r_n = 1, 0

    while queue:
        x, y = queue.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < n and 0 <= ny < n:
                if board[nx][ny] == c and visited[nx][ny] == 0:
                    size += 1
                    visited[nx][ny] = b_num
                    queue.append((nx, ny))
                elif board[nx][ny] == 0 and not b_num in visited[nx][ny]:
                    size += 1
                    r_n += 1
                    visited[nx][ny].append(b_num)
                    queue.append((nx, ny))
    # 블둝 그룹의 μ‚¬μ΄μ¦ˆμ™€, 블둝 κ·Έλ£Ή μ•ˆμ— μžˆλŠ” λ¬΄μ§€κ°œ λΈ”λ‘μ˜ 갯수
    return size, r_n

# 쀑λ ₯
def fall(x, y) :
    stop = False
    for i in range(x + 1, n) :
        nx = i
        if board[nx][y] != -2 :
            stop = True
            break
    if stop :
        board[nx-1][y] = board[x][y]
    else :
        board[nx][y] = board[x][y]
    # 블둝을 μ œκ±°ν•œλ‹€. 제거 μ‹œ -2κ°’μœΌλ‘œ λ³€κ²½ν•œλ‹€. 
    board[x][y] = -2

score = 0
while True:
    visited = [[0]*n for _ in range(n)]
    for i in range(n):
        for j in range(n):
            if board[i][j] == 0:
                visited[i][j] = []

    b_num, block = 1, []
    for i in range(n):
        for j in range(n):
            if board[i][j] > 0 and visited[i][j] == 0:
                # # 블둝 그룹의 μ‚¬μ΄μ¦ˆμ™€, 블둝 κ·Έλ£Ή μ•ˆμ— μžˆλŠ” λ¬΄μ§€κ°œ λΈ”λ‘μ˜ 갯수
                size, r_n = bfs(i, j, visited, b_num)
                if size > 1:
                    # 그룹의 크기, λ¬΄μ§€κ°œλΈ”λ‘μ˜ 갯수, 블둝 κΈ°μ€€ ν–‰, μ—΄, 블둝 번호
                    block.append([size, r_n, i, j, b_num])
                b_num += 1
    if len(block) == 0:
        break
    # 블둝 그룹의 크기 -> λ¬΄μ§€κ°œ λΈ”λ‘μ˜ 갯수 -> 블둝 κΈ°μ€€μ˜ ν–‰ -> μ—΄
    block.sort(key=lambda x:(-x[0], -x[1], -x[2], -x[3]))
    count = 0
    for i in range(n):
        for j in range(n):
            if board[i][j] > 0 and visited[i][j] == block[0][4]:
                count += 1
                board[i][j] = -2
            elif board[i][j] == 0 and block[0][4] in visited[i][j]:
                count += 1
                board[i][j] = -2

    score += (count*count)
    for i in range(n-2, -1, -1):
        for j in range(n):
            # 블둝을 μ œκ±°ν•œλ‹€. 제거 μ‹œ -2κ°’μœΌλ‘œ λ³€κ²½ν•œλ‹€. 
            if board[i][j] >= 0 and board[i+1][j] == -2:
                fall(i, j)

    board = list(map(list, zip(*board)))[::-1]

    for i in range(n-2, -1, -1):
        for j in range(n):
            # 블둝을 μ œκ±°ν•œλ‹€. 제거 μ‹œ -2κ°’μœΌλ‘œ λ³€κ²½ν•œλ‹€. 
            if board[i][j] >= 0 and board[i+1][j] == -2:
                fall(i, j)


print(score)

예제 μž…λ ₯

5 3
2 2 -1 3 1
3 3 2 0 -1
0 0 0 1 2
-1 3 1 3 2
0 3 2 2 1

예제 좜λ ₯

77

 

 

 

μ΄λ²ˆκ»€.. 쫌.. μ½”λ“œ 해석이 μ–΄λ €μ› λ‹€.

λ‹€μ‹œ 도전할 κ²ƒμž„.

https://developer-ellen.tistory.com/75

728x90
λ°˜μ‘ν˜•
Comments