from collections import deque
R, C = map(int, input().split(" "))
dy = [0, 0, 1, -1]
dx = [1, -1, 0, 0]
board = []
r_y = 0
r_x = 0
b_y = 0
b_x = 0
for i in range(R):
row = list(input())
board.append(row)
for j in range(len(row)):
if row[j] == "R":
r_y = i
r_x = j
board[i][j] = "."
if row[j] == "B":
b_y = i
b_x = j
board[i][j] = "."
queue = deque()
queue.append((r_y, r_x, b_y, b_x, 1))
visit = set([(r_y, r_x, b_y, b_x)])
def move(y, x, i):
cnt = 0
while board[y][x] != "O" and board[y][x] != "#":
y += dy[i]
x += dx[i]
cnt += 1
if board[y][x] == "O":
return [y, x, cnt]
if board[y][x] == "#":
return [y - dy[i], x - dx[i], cnt]
find = False
while queue:
cur_ry, cur_rx, cur_by, cur_bx, cur_k = queue.popleft()
if cur_k > 10:
continue
if find:
break
for i in range(4):
next_ry, next_rx, r_cnt = move(cur_ry, cur_rx, i)
next_by, next_bx, b_cnt = move(cur_by, cur_bx, i)
if board[next_ry][next_rx] == "O" and board[next_by][next_bx] == "O":
continue
if board[next_ry][next_rx] == "O" and board[next_by][next_bx] != "O":
find = True
print(cur_k)
break
if next_ry == next_by and next_rx == next_bx:
if r_cnt < b_cnt:
next_by -= dy[i]
next_bx -= dx[i]
if r_cnt > b_cnt:
next_ry -= dy[i]
next_rx -= dx[i]
if (next_ry, next_rx, next_by, next_bx) not in visit:
queue.append((next_ry, next_rx, next_by, next_bx, cur_k + 1))
visit.add((next_ry, next_rx, next_by, next_bx))
if not find:
print(-1)
구슬 탈출 문제로 주요 로직은 구슬 겹침 문제인 것 같다.
처음에는 구슬을 따로따로 한 칸씩 움직여 로직을 구성했었다.
from collections import deque
R, C = map(int, input().split(" "))
dy = [0, 0, 1, -1]
dx = [1, -1, 0, 0]
board = []
r_y = 0
r_x = 0
b_y = 0
b_x = 0
for i in range(R):
row = list(input())
board.append(row)
for j in range(len(row)):
if row[j] == "R":
r_y = i
r_x = j
board[i][j] = "."
if row[j] == "B":
b_y = i
b_x = j
board[i][j] = "."
queue = deque()
queue.append((r_y, r_x, b_y, b_x, 1))
visit = set([(r_y, r_x, b_y, b_x)])
find = False
while queue:
cur_ry, cur_rx, cur_by, cur_bx, cur_k = queue.popleft()
if find:
break
# print(f"ry : {cur_ry}, rx : {cur_rx} | by : {cur_by}, bx : {cur_bx}")
if cur_k > 10:
continue
for i in range(4):
if find:
break
r_stop = False
b_stop = False
next_ry = cur_ry
next_rx = cur_rx
next_by = cur_by
next_bx = cur_bx
r_in_hole = False
b_in_hole = False
while (not r_stop or not b_stop):
nnry = next_ry + dy[i]
nnrx = next_rx + dx[i]
# print(f"ry : {next_ry}, rx : {next_rx} | by : {next_by}, bx : {next_bx}")
if (not r_stop and (0 <= nnry < R and 0 <= nnrx < C)) and (nnry != next_by or nnrx != next_bx):
next_ry += dy[i]
next_rx += dx[i]
nnby = next_by + dy[i]
nnbx = next_bx + dx[i]
if (not b_stop and (0 <= nnby < R and 0 <= nnbx < C)) and (nnby != next_ry or nnbx != next_rx):
next_by += dy[i]
next_bx += dx[i]
if board[next_ry][next_rx] == "#":
r_stop = True
board[next_ry - dy[i]][next_rx - dx[i]] = "#"
if board[next_by][next_bx] == "#":
b_stop = True
board[next_by - dy[i]][next_bx - dx[i]] = "#"
if board[next_ry][next_rx] == "O":
r_in_hole = True
if board[next_by][next_bx] == "O":
b_in_hole = True
next_ry -= dy[i]
next_rx -= dx[i]
next_by -= dy[i]
next_bx -= dx[i]
board[next_ry][next_rx] = "."
board[next_by][next_bx] = "."
if not (next_ry, next_rx, next_by, next_bx) in visit:
queue.append((next_ry, next_rx, next_by, next_bx, cur_k + 1))
visit.add((next_ry, next_rx, next_by, next_bx))
# print(f"result : ry : {next_ry}, rx : {next_rx} | by : {next_by}, bx : {next_bx}\n")
if r_in_hole and not b_in_hole:
find = True
print(cur_k)
break
if not find:
print(-1)
겹침 문제는 동시에 공을 굴리고 움직인 수가 더 많은 공을 한 칸 뒤로 미는것으로 수정했다.