문제 풀이/[BaekJoon]

[BaekJoon] 3197 백조의 호수 (Platinum 5) - Python

조랩 2023. 1. 25. 19:13

문제

 

두 마리의 백조가 호수에서 살고 있었다. 그렇지만 두 마리는 호수를 덮고 있는 빙판으로 만나지 못한다.

호수는 행이 R개, 열이 C개인 직사각형 모양이다. 어떤 칸은 얼음으로 덮여있다.

호수는 차례로 녹는데, 매일 물 공간과 접촉한 모든 빙판 공간은 녹는다. 두 개의 공간이 접촉하려면 가로나 세로로 닿아 있는 것만 (대각선은 고려하지 않는다) 생각한다.

아래에는 세 가지 예가 있다.

...XXXXXX..XX.XXX ....XXXX.......XX .....XX.......... 
....XXXXXXXXX.XXX .....XXXX..X..... ......X.......... 
...XXXXXXXXXXXX.. ....XXX..XXXX.... .....X.....X..... 
..XXXXX..XXXXXX.. ...XXX....XXXX... ....X......XX.... 
.XXXXXX..XXXXXX.. ..XXXX....XXXX... ...XX......XX.... 
XXXXXXX...XXXX... ..XXXX.....XX.... ....X............ 
..XXXXX...XXX.... ....XX.....X..... ................. 
....XXXXX.XXX.... .....XX....X..... ................. 
      처음               첫째 날             둘째 날

백조는 오직 물 공간에서 세로나 가로로만(대각선은 제외한다) 움직일 수 있다.

며칠이 지나야 백조들이 만날 수 있는 지 계산하는 프로그램을 작성하시오.


입출력 예시

 

입력: 입력의 첫째 줄에는 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1500.

다음 R개의 줄에는 각각 길이 C의 문자열이 하나씩 주어진다. '.'은 물 공간, 'X'는 빙판 공간, 'L'은 백조가 있는 공간으로 나타낸다.

출력: 첫째 줄에 문제에서 주어진 걸리는 날을 출력한다.

 

입력예시1)

10 2
.L
..
XX
XX
XX
XX
XX
XX
..
.L

출력예시1)

3

 

입력예시2)

4 11
..XXX...X..
.X.XXX...L.
....XXX..X.
X.L..XXX...

출력예시2)

2

 

입력예시3)

8 17
...XXXXXX..XX.XXX
....XXXXXXXXX.XXX
...XXXXXXXXXXXX..
..XXXXX.LXXXXXX..
.XXXXXX..XXXXXX..
XXXXXXX...XXXX...
..XXXXX...XXX....
....XXXXX.XXXL...

출력예시3)

2

 


코드

 

bfs로 두 백조가 만날 수 있는지 찾는 코드는 할만 했는데 ,,,,,

bfs탐색을 위한 얼음 위치정보? 그걸 어케해야할지 몰라서 인터넷 여기저기 보고 했다....

 

생각보다 원리는 쉽드라

좀만 더 생각해볼걸

 

1. 백조 위치를 따로 리스트에 저장하고, L을 .으로 바꾼다. (탐색하기 쉽게 하려고 그랬다고 한다.)

2. 다음날에 녹을 위치에 있는 얼음의 위치를 리스트에 저장한다.

3. 이 리스트를 bfs함수에 매개변수로 넘겨준다.

    - bfs함수에서는 얼음 위치의 상하좌우를 탐색한다.

    - 매개변수로 넘겨준 얼음 위치 리스트에서 한 개씩 pop하여 사용한다.

    - 얼음 위치를 물('.')로 바꾸고, 상하좌우에 얼음이 있을 경우, 얼음이 있는 칸의 위치를 buf리스트에 추가한다.

    - 얼음 위치 상하좌우에 물이 있는 경우 union_list에 물의 위치를 추가한다.

    - 상하좌우 탐색이 끝나면 union_list에 있는 물의 위치와 현재 얼음의 위치를 union한다.

    - 얼음 위치 리스트가 비어있을 때 까지 반복.

    - buf리스트를 return 한다

4. bfs함수에서 return한 buf를 melt에 저장하고, 이 melt를 다시 bfs함수의 매개변수로 전달한다.

5. 3, 4를 두 백조가 만날 수 있을 때 까지 반복하고, 반복한 횟수를 day변수에 저장한다

6. day변수 출력

import sys
from collections import deque

input = sys.stdin.readline

dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]

N, M = map(int, input().rstrip().split())

grid = [list(input()) for _ in range(N)]
root = [[(i, j) for j in range(M)] for i in range(N)]
visit = [[False for _ in range(M)] for _ in range(N)]
swan = []

def in_range(x, y):
    return (0 <= x < N and 0 <= y < M)

def find(x, y):
    if (x, y) == root[x][y]:
        return (x, y)
    root[x][y] = find(root[x][y][0], root[x][y][1])
    return root[x][y]

def union(x1, y1, x2, y2):
    x1, y1 = find(x1, y1)
    x2, y2 = find(x2, y2)
    root[x2][y2] = (x1, y1)

def bfs(melt):
    buf = deque()
    while melt:
        x, y = melt.popleft()
        grid[x][y] = "."
        union_list = []
        for k in range(4):
            nx = x + dx[k]
            ny = y + dy[k]
            if in_range(nx, ny) and not visit[nx][ny] and grid[nx][ny] == "X":
                visit[nx][ny] = True
                buf.append((nx, ny))
            elif in_range(nx, ny) and grid[nx][ny] == ".":
                union_list.append((nx, ny))
        for a in union_list:
            bx, by = a[0], a[1]
            if find(bx, by) != find(x, y):
                union(bx, by, x, y)
    return buf


for i in range(N):
    for j in range(M):
        if grid[i][j] == "L":
            swan.append((i, j))
            grid[i][j] = "."
            if len(swan) == 2:
                break


melt = deque()
for i in range(N):
    for j in range(M):
        if not visit[i][j] and grid[i][j] == ".":
            q = deque()
            q.append((i, j))
            visit[i][j] = 1
            while q:
                x, y = q.popleft()
                root[x][y] = (i, j)
                for k in range(4):
                    ny, nx = y + dy[k], x + dx[k]
                    if in_range(nx, ny) and not visit[nx][ny] and grid[nx][ny] == ".":
                        visit[nx][ny] = True
                        q.append((nx, ny))
                    elif in_range(nx, ny) and not visit[nx][ny] and grid[nx][ny] == "X":
                        visit[nx][ny] = True
                        melt.append((nx, ny))


day = 0
while find(swan[0][0], swan[0][1]) != find(swan[1][0], swan[1][1]):
    melt = bfs(melt)
    day += 1

print(day)

실행 화면

 


채점 결과

푸는데 1주일 걸려써 ㅇ.ㅇ

공부 더 해야게다

728x90