본문 바로가기
Problem Solving/BOJ

[Python]13460. 구슬 탈출 2

by 부르르 2019. 5. 10.

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

 

13460번: 구슬 탈출 2

첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B' 로 이루어져 있다. '.'은 빈 칸을 의미하고, '#'은 공이 이동할 수 없는 장애물 또는 벽을 의미하며, 'O'는 구멍의 위치를 의미한다. 'R'은 빨간 구슬의 위치, 'B'는 파란 구슬의 위치이다. 입력되는 모든 보드

www.acmicpc.net


 

어느 방향으로 기울이는가에 따라 queue에 Red와 Blue의 좌표를 초기화 해주어야 한다.(중요!)

또한 현재 Red 와 Blue의 좌표를 계속 visited에 넣어주어서 이미 방문한 좌표에서의 재귀호출은 하지 않는다.

 

  1. 최초의 Red, Blue 좌표를 매개변수로 recur() 호출
  2. 현재의 Red, Blue 좌표를 가지고 4가지 방향으로 기울이면서 방문한 적이 없는 좌표로만 움직임
  3. recur() 함수의 result 매개변수가 True일 때 빨간공만 탈출한 것이다. 이때의 depth로 최소값 없데이트한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from copy import deepcopy
 
def move_dir(MAP, red, blue, flag):
    global n, m
    queue = []
    if flag == 0:
        if red[0< blue[0]:
            queue = [red, blue]
        else:
            queue = [blue, red]
    elif flag == 1:
        if red[0> blue[0]:
            queue = [red, blue]
        else:
            queue = [blue, red]
    elif flag == 2:
        if red[1< blue[1]:
            queue = [red, blue]
        else:
            queue = [blue, red]
    elif flag == 3:
        if red[1> blue[1]:
            queue = [red, blue]
        else:
            queue = [blue, red]
 
    next_balls = {'R': None, 'B': None}
 
    while queue:
        r, c = queue.pop(0)
        if MAP[r][c] == 'R':
            opposite = 'B'
        else:
            opposite = 'R'
        isColorOut = False
        while True:
            n_r = r + d[flag][0]
            n_c = c + d[flag][1]
            if 0 <= n_r < n and 0 <= n_c < m:
                if MAP[n_r][n_c] == '#' or MAP[n_r][n_c] == opposite:
                    break
                elif MAP[n_r][n_c] == '.':
                    MAP[n_r][n_c], MAP[r][c] = MAP[r][c], MAP[n_r][n_c]
                elif MAP[n_r][n_c] == 'O':
                    isColorOut = True
                    MAP[r][c] = '.'
                    r, c = n_r, n_c
                    break
                r, c = n_r, n_c
        next_balls[MAP[r][c]] = [isColorOut, (r,c)]
    return next_balls
 
def tilt(MAP_origin, flag, red, blue):
    MAP = deepcopy(MAP_origin)
    next_balls = move_dir(MAP, red, blue, flag)
    if next_balls['R'is None:
        isRedOut, (r_r, r_c) = next_balls['O']
    else:
        isRedOut, (r_r, r_c) = next_balls['R']
    if next_balls['B'is None:
        isBlueOut, (b_r, b_c) = next_balls['O']
    else:
        isBlueOut, (b_r, b_c) = next_balls['B']
    if not isBlueOut and isRedOut:
        return True, MAP, (r_r, r_c), (b_r, b_c)
    else:
        return False, MAP, (r_r, r_c), (b_r, b_c)
 
def recur(depth, result, MAP, red, blue):
    global answer, n, m
    if depth > 10 :
        return
    if depth <= 10 and result:
        answer = min(answer, depth)
        return
    for i in range(4):
        _result, tilted_MAP, new_red, new_blue = tilt(MAP, i, red, blue)
        if (new_red, new_blue) not in visited:
            visited.append((new_red, new_blue))
            recur(depth+1, _result, tilted_MAP, new_red, new_blue)
            visited.pop()
 
 
n, m = map(int, input().split())
MAP = [list(input()) for _ in range(n)]
= ((-1,0), (1,0), (0,-1), (0,1))
answer = 9876543210
 
for r in range(n):
    for c in range(m):
        if MAP[r][c] == 'R':
            red = (r,c)
        elif MAP[r][c] == 'B':
            blue = (r,c)
 
visited = [(red, blue)]
recur(0, False, MAP, red, blue)
if answer == 9876543210:
    answer = -1
print(answer)
cs
728x90
반응형

'Problem Solving > BOJ' 카테고리의 다른 글

[Python] 3190. 뱀  (0) 2021.04.03
[Python]3678. 카탄의 개척자  (0) 2019.05.11
[Python]14502. 연구소  (0) 2019.05.09
[Python]12100. 2048 (Easy)  (0) 2019.05.08
[Python]1248. 맞춰봐  (0) 2019.04.22

댓글