본문 바로가기

코테

2개의 사탕

728x90
반응형
SMALL

 

백트래킹 없이는 시간 초과가 나는 문제였습니다.

그래서 딕셔너리에 현재의 위치와 방향을 key로 그리고 움직인 횟수를 value 갱신해줬더니 풀렸습니다. 헿

 

import sys, copy, math
from collections import deque
n, m = map(int, sys.stdin.readline().strip().split())
graph = [list(sys.stdin.readline().strip()) for _ in range(n)]
answer = math.inf
b_y, b_x = 0, 0
r_y, r_x = 0, 0
g_y, g_x = 0, 0
dy, dx = [-1, 0, 1, 0], [0, 1, 0, -1]
move_dict = {}
def find_first_candy(d, r_y, r_x, b_y, b_x):
    if d == 0: #왼쪽 기울일 때
        if r_x != b_x:
            return "Red"
        if r_y < b_y:
            return "Red"
        return "Blue"
    elif d == 1:
        if r_y != b_y:
            return "Red"
        if r_x > b_x:
            return "Red"
        return "Blue"
    elif d == 2:
        if r_x != b_x:
            return "Red"
        if r_y > b_y:
            return "Red"
        return "Blue"
    elif d == 3:
        if r_y != b_y:
            return "Red"
        if r_x < b_x:
            return "Red"
        return "Blue"

def find_red_blue_goal():
    global graph, n, m, b_y, b_x, r_y, r_x, g_y, g_x
    for y in range(n):
        for x in range(m):
            if graph[y][x] == "B":
                b_y, b_x = y, x
            elif graph[y][x] == "R":
                r_y, r_x = y, x
            elif graph[y][x] == "O":
                g_y, g_x = y, x

def validation(ny, nx):
    global n, m
    return 0 <= ny < n and 0 <= nx < m
    
def dfs(b_y, b_x, r_y, r_x, g_y, g_x, graph, count, d):
    # print(b_y, b_x, r_y, r_x, g_y, g_x, count, d)
    # for i in graph:
    #     print(i)
    # print()
    global answer, move_dict
    if (b_y, b_x, r_y, r_x, d) in move_dict:
        if move_dict[(b_y, b_x, r_y, r_x, d)] <= count:
            return
    move_dict[(b_y, b_x, r_y, r_x, d)] = count
    
    if count > 10:
        return

    tmp_graph = copy.deepcopy(graph)

    if b_y == -1 and r_y == -1:  #둘다 빠지면 그냥 return
        return
    if b_y != -1 and r_y == -1: 
        answer = min(answer, count)

    first_candy = find_first_candy(d, r_y, r_x, b_y, b_x)
    if first_candy == "Red":
        q = deque([])
        q.append((r_y, r_x))
        while q:
            y, x = q.popleft()
            ny = y + dy[d]
            nx = x + dx[d]
            if validation(ny, nx):
                if tmp_graph[ny][nx] == "#" or tmp_graph[ny][nx] == "B":
                    continue
                if tmp_graph[ny][nx] == ".":
                    tmp_graph[y][x], tmp_graph[ny][nx] = ".", "R"
                    r_y, r_x = ny, nx
                    q.append((ny, nx))
                    
                if tmp_graph[ny][nx] == "O":
                    tmp_graph[y][x] = "."
                    r_y, r_x = -1, -1
        q = deque([])
        q.append((b_y, b_x))
        while q:
            y, x = q.popleft()
            ny = y + dy[d]
            nx = x + dx[d]
            if validation(ny, nx):
                if tmp_graph[ny][nx] == "#" or tmp_graph[ny][nx] == "R":
                    continue
                if tmp_graph[ny][nx] == ".":
                    tmp_graph[y][x], tmp_graph[ny][nx] = ".", "B"
                    b_y, b_x = ny, nx
                    q.append((ny, nx))
                    
                if tmp_graph[ny][nx] == "O":
                    tmp_graph[y][x] = "."
                    b_y, b_x = -1, -1

    else:
        q = deque([])
        q.append((b_y, b_x))
        while q:
            y, x = q.popleft()
            ny = y + dy[d]
            nx = x + dx[d]
            if validation(ny, nx):
                if tmp_graph[ny][nx] == "#" or tmp_graph[ny][nx] == "R":
                    continue
                if tmp_graph[ny][nx] == ".":
                    tmp_graph[y][x], tmp_graph[ny][nx] = ".", "B"
                    b_y, b_x = ny, nx
                    q.append((ny, nx))
                    
                if tmp_graph[ny][nx] == "O":
                    tmp_graph[y][x] = "."
                    b_y, b_x = -1, -1

        q = deque([])
        q.append((r_y, r_x))
        while q:
            y, x = q.popleft()
            ny = y + dy[d]
            nx = x + dx[d]
            if validation(ny, nx):
                if tmp_graph[ny][nx] == "#" or tmp_graph[ny][nx] == "B":
                    continue
                if tmp_graph[ny][nx] == ".":
                    tmp_graph[y][x], tmp_graph[ny][nx] = ".", "R"
                    r_y, r_x = ny, nx
                    q.append((ny, nx))
                    
                if tmp_graph[ny][nx] == "O":
                    tmp_graph[y][x] = "."
                    r_y, r_x = -1, -1

    for d in range(4):
        dfs(b_y, b_x, r_y, r_x, g_y, g_x, tmp_graph, count + 1, d)
    
find_red_blue_goal()

for d in range(4):
    dfs(b_y, b_x, r_y, r_x, g_y, g_x, graph, 0, d)
    dfs(b_y, b_x, r_y, r_x, g_y, g_x, graph, 0, d)
    dfs(b_y, b_x, r_y, r_x, g_y, g_x, graph, 0, d)
    dfs(b_y, b_x, r_y, r_x, g_y, g_x, graph, 0, d)

if answer == math.inf:
    print(-1)
else:
    print(answer)
728x90
반응형
LIST

'코테' 카테고리의 다른 글

바이러스 검사  (0) 2023.03.28
생명과학부 랩 인턴  (0) 2023.03.28
시공의 돌풍  (0) 2023.03.28
팩맨  (0) 2023.03.27
꼬리잡기놀이  (0) 2023.03.25