Algorithm

[백준][python]2234 성곽

soduddl1 2023. 6. 6. 14:27

문제

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

소스코드

import sys
from collections import deque
input = sys.stdin.readline
if __name__ == "__main__":
    m,n = map(int,input().split())
    room_input = [list(map(int,input().split())) for _ in range(n)]
    room_2 = [[] for _ in range(n)]
    for i in range(n):
        for j in range(m):
            changeVal = bin(room_input[i][j])[2:]
            room_2[i].append(list(map(int,'0'*(4-len(changeVal))+changeVal)))

    def bfs(X,Y):
        dx = [1,0,-1,0]
        dy = [0,1,0,-1]

        q = deque()
        q.append([X, Y])
        cnt = 1

        while q:
            x, y = q.popleft()
            for kk in range(4):
                if not room_2[x][y][kk]:
                    xx = x + dx[kk]
                    yy = y + dy[kk]
                    if 0 <= xx < n and 0 <= yy < m and not visited[xx][yy]:
                        q.append([xx, yy])
                        visited[xx][yy] = 1
                        cnt += 1
        return cnt

    visited = [[0] * m for _ in range(n)]
    res1,res2 = 0,0
    for i in range(n):
        for j in range(m):
            if not visited[i][j]:
                visited[i][j] = 1
                res1 +=1
                res2 = max(bfs(i,j),res2)

    res3 = 0
    for i in range(n):
        for j in range(m):
            for k in range(2):
                if room_2[i][j][k]:
                    room_2[i][j][k] = 0
                    visited = [[0] * m for _ in range(n)]
                    for xx in range(n):
                        for yy in range(m):
                            if not visited[xx][yy]:
                                visited[xx][yy] = 1
                                res3 = max(bfs(xx,yy),res3)
                    room_2[i][j][k] = 1

    print(res1)
    print(res2)
    print(res3)

설명

문제에 나와있는 2진수와 방향, 갈 수 있는 정보를 치환하면 아래와 같다.

8421:남동북서(아래 오른쪽 위 왼쪽), 0이면 갈 수 있음

 

1. 들어오는 숫자를 4자리 이진수로 치환해준다.

2. bfs를 이용해서 방의 갯수과와 방의 넓이를 계산해준다. (2번과 3번을 동시에 할 수 없어서 bfs를 따로 함수로 빼주었다.)

3. 백트래킹을 이용해서 벽을 하나씩 지워준다.

3-1. 벽을 지운 후 bfs를 이용해서 2번 과정을 거쳐 최대 방의 넓이를 계산해준다.

3-2. bfs를 체크할 때 인접한 부분은 탐색을 피해야하기 때문에 아래쪽과 오른쪽만 탐색해줬다. (왼쪽과 위쪽은 그 전 단계의 오른쪽과 아래쪽이기 때문이다)

 

 

 

후기

3번 과정을 보면 4중 포문을 써야한다;;; python으로는 시간초과가 나고 pypy로 통과했다. 수정할 수 있는 방법을 생각해봐야겠다.