백준

[백준] 14500번: 테트로미노 (파이썬)

초코바나나쉐이크 2025. 1. 6. 23:14

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

 

문제를 읽고, BFS가 먼저 생각났다.

from collections import deque
n,m = map(int,input().split())
graph = [ list(map(int,input().split())) for _ in range(n)]

#방향
dx = [1, 0, -1, 0]
dy = [0, -1, 0, 1]

4방향을 탐색해야 하므로, 방향 리스트를 만들어 준다.

result = 0

for i in range(n):
    for j in range(m):
        score = search(i,j)
        result = max(result, score)
print(result)

모든 좌표에서 나올 수 있는 점수중에 가장 큰 점수를 출력해준다.

def search(x,y):
    queue = deque([(x,y,-1,graph[x][y])])
    max_score = 0
    for count in range(1,4):
        length = len(queue)
        for _ in range(length):
            nx,ny,prev_dir,score = queue.popleft()
            
            #ㅗ모양
            if ny == y + 2:
              
                if 0 <= nx-1 < n and 0 <= ny - 1 < m:
                    
                    max_score = max(max_score, score+graph[nx-1][ny-1])
                if 0 <= nx + 1 < n and 0 <= ny - 1 < m:
                    
                    max_score = max(max_score, score+graph[nx+1][ny-1])
               
            elif nx == x + 2:
               
                if 0 <= nx - 1 < n and 0 <= ny + 1 < m:
                    
                    max_score = max(max_score, score+graph[nx-1][ny+1])
                if 0 <= nx - 1 < n and 0 <= ny - 1 < m:
                   
                    max_score = max(max_score, score+graph[nx-1][ny-1])
                

            for i in range(4):
                if i != (prev_dir+2)%4 or prev_dir == -1:
                    current_x, current_y = nx + dx[i], ny + dy[i]
                    if 0 <= current_x < n and 0 <= current_y < m:
                        current_score = score + graph[current_x][current_y]
                        max_score = max(max_score, current_score)
                        queue.append((current_x,current_y,i,current_score))

    return max_score

해당 좌표의 최대 점수를 구하는 함수이다.

queue = deque([(x,y,-1,graph[x][y])])

queue에 시작점의 x좌표, y좌표, 전 방향, 해당 좌표의 점수를 추가해 준다.

여기서 전 방향을 저장하는 이유는 예를 들어, 시작점에서 밑 방향으로 움직였을 때 다음에 윗 방향으로 움직이면 제자리 걸음을 하게 되니 전에 있던 방향으로 움직이는 것을 막기 위해서이다.

for count in range(1,4):
        length = len(queue)
        for _ in range(length):
            nx,ny,prev_dir,score = queue.popleft()

각 칸마다 움직을 수 있는 모든 경우를 생각해야 한다.

	for i in range(4):
                if i != (prev_dir+2)%4 or prev_dir == -1:
                    current_x, current_y = nx + dx[i], ny + dy[i]
                    if 0 <= current_x < n and 0 <= current_y < m:
                        current_score = score + graph[current_x][current_y]
                        max_score = max(max_score, current_score)
                        queue.append((current_x,current_y,i,current_score))

4방향을 모두 탐색한다.

이 때 전에 움직였던 방향의 반대방향으로는 움직일 수 없다.

 

그런데, 이렇게만 하면 ㅏ,ㅓ,ㅗ,ㅜ 모양을 구할 수 없다.

ㅏ,ㅓ,ㅗ,ㅜ 모양을 따로 구해야 한다.

            if ny == y + 2:
              
                if 0 <= nx-1 < n and 0 <= ny - 1 < m:
                    # ㅗ 모양
                    max_score = max(max_score, score+graph[nx-1][ny-1])
                if 0 <= nx + 1 < n and 0 <= ny - 1 < m:
                    # ㅜ 모양
                    max_score = max(max_score, score+graph[nx+1][ny-1])
               
            elif nx == x + 2:
               
                if 0 <= nx - 1 < n and 0 <= ny + 1 < m:
                    # ㅏ 모양
                    max_score = max(max_score, score+graph[nx-1][ny+1])
                if 0 <= nx - 1 < n and 0 <= ny - 1 < m:
                    # ㅓ 모양
                    max_score = max(max_score, score+graph[nx-1][ny-1])

ny가 y+2일 경우는 오른쪽으로 2번 이동한 경우이기 때문에 ㅗ나 ㅜ가 나올 수 있다.

비슷하게 nx가 x+2일 경우는 밑으로 두 번 이동한 경우이기 때문에 ㅏ나 ㅓ가 나올 수 있다.

 

[전체 코드]

from collections import deque
n,m = map(int,input().split())
graph = [ list(map(int,input().split())) for _ in range(n)]

#방향
dx = [1, 0, -1, 0]
dy = [0, -1, 0, 1]

def search(x,y):
    queue = deque([(x,y,-1,graph[x][y])])
    max_score = 0
    for count in range(1,4):
        length = len(queue)
        for _ in range(length):
            nx,ny,prev_dir,score = queue.popleft()
            
            #ㅗ모양
            if ny == y + 2:
              
                if 0 <= nx-1 < n and 0 <= ny - 1 < m:
                    
                    max_score = max(max_score, score+graph[nx-1][ny-1])
                if 0 <= nx + 1 < n and 0 <= ny - 1 < m:
                    
                    max_score = max(max_score, score+graph[nx+1][ny-1])
               
            elif nx == x + 2:
               
                if 0 <= nx - 1 < n and 0 <= ny + 1 < m:
                    
                    max_score = max(max_score, score+graph[nx-1][ny+1])
                if 0 <= nx - 1 < n and 0 <= ny - 1 < m:
                   
                    max_score = max(max_score, score+graph[nx-1][ny-1])
                

            for i in range(4):
                if i != (prev_dir+2)%4 or prev_dir == -1:
                    current_x, current_y = nx + dx[i], ny + dy[i]
                    if 0 <= current_x < n and 0 <= current_y < m:
                        current_score = score + graph[current_x][current_y]
                        max_score = max(max_score, current_score)
                        queue.append((current_x,current_y,i,current_score))

    return max_score
    


result = 0

for i in range(n):
    for j in range(m):
        score = search(i,j)
        result = max(result, score)
print(result)

오랜만에 누군가의 도움없이 내 힘만으로 푼 문제였다.

매우 뿌듯하다😊