코테/BOJ

백준 9328 [열쇠] 파이썬

동 캄 2025. 3. 11. 19:28
반응형

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

 

거의 다 왔으나, 코드 최적화를 못해서 아쉽게 놓쳤다.... 

 

#백준 9328 열쇠
import sys
from collections import deque
dr=[0,0,1,-1]
dc=[1,-1,0,0]

T=int(sys.stdin.readline().rstrip())
for _ in range(T):
    ans=0
    N,M=map(int,sys.stdin.readline().split())
    visited=[[0 for _ in range(M)] for _ in range(N)]
    maps=[]
    needed_key_points=deque()
    keys=[]
    q=deque()
    for i in range(N):
        s=list(map(str,sys.stdin.readline().rstrip()))
        maps.append(s)
        for j in range(M):
                if i==0 or i==N-1 or j==0 or j==M-1:
                    if s[j]=='.':
                        q.append((i,j))
                    elif s[j]=='$':
                        q.append((i,j))
                        ans+=1
                        maps[i][j]='.'
                    elif 'a'<=maps[i][j]<='z':
                        q.append((i,j))
                        keys.append(s[j])
                        maps[i][j]='.'
                    elif 'A'<=maps[i][j]<='Z':
                        needed_key_points.append((i,j,maps[i][j]))
    keys.extend(list(map(str,sys.stdin.readline().rstrip())))

    for i in range(len(needed_key_points)):
        if chr(ord(needed_key_points[i][2])+32) in keys:
            q.append((needed_key_points[i][0],needed_key_points[i][1]))
    needed_key_points=[need_key_point for need_key_point in needed_key_points if need_key_point[2] not in keys]

    while q:
        r,c=q.popleft()
        visited[r][c]=1
        for i in range(4):
            R=r+dr[i]
            C=c+dc[i]
            if 0<=R<N and 0<=C<M and visited[R][C]==0:
                if maps[R][C]=='.':
                    q.append((R,C))
                elif maps[R][C]=='$':
                    ans+=1
                    q.append((R,C))
                    maps[R][C]='.'
                elif maps[R][C] in keys:
                    q.append((R,C))
                    maps[R][C]='.'
                elif 'a' <= maps[R][C] <='z':
                    q.append((R,C))
                    keys.append(maps[R][C])
                    new_key=chr(ord(maps[R][C])-32)
                    find_point=[]
                    for i in range(len(needed_key_points)):
                        if new_key==needed_key_points[i][2]:
                            q.append((needed_key_points[i][0],needed_key_points[i][1]))
                            find_point.append(needed_key_points[i][2])
                    needed_key_points=[need_key_point for need_key_point in needed_key_points if need_key_point[2] not in find_point]
                    maps[R][C]='.'
                elif 'A' <= maps[R][C] <='Z':
                    if chr(ord(maps[R][C])+32) in keys:
                        q.append((R,C))
                        maps[R][C]='.'
                    else:
                        needed_key_points.append((R,C,maps[R][C]))
    print(ans)

 

 

CHAT GPT의 코드를 첨부한다.

import sys
from collections import deque, defaultdict

dr = [0, 0, 1, -1]
dc = [1, -1, 0, 0]

T = int(sys.stdin.readline().rstrip())
for _ in range(T):
    ans = 0
    N, M = map(int, sys.stdin.readline().split())
    visited = [[0] * M for _ in range(N)]
    maps = []
    needed_key_points = defaultdict(list)
    keys = set()
    q = deque()

    for i in range(N):
        row = list(sys.stdin.readline().rstrip())
        maps.append(row)
        for j in range(M):
            if i == 0 or i == N - 1 or j == 0 or j == M - 1:
                if row[j] == '.':
                    q.append((i, j))
                    visited[i][j] = 1
                elif row[j] == '$':
                    q.append((i, j))
                    visited[i][j] = 1
                    ans += 1
                    maps[i][j] = '.'
                elif 'a' <= row[j] <= 'z':
                    q.append((i, j))
                    visited[i][j] = 1
                    keys.add(row[j])
                    maps[i][j] = '.'
                elif 'A' <= row[j] <= 'Z':
                    needed_key_points[row[j]].append((i, j))

    for key in sys.stdin.readline().rstrip():
        if key != '0':
            keys.add(key)

    for key in list(keys):  # 이미 있는 키로 문 열기
        if key.upper() in needed_key_points:
            for r, c in needed_key_points[key.upper()]:
                q.append((r, c))
                visited[r][c] = 1
            del needed_key_points[key.upper()]

    while q:
        r, c = q.popleft()

        for i in range(4):
            R, C = r + dr[i], c + dc[i]
            if 0 <= R < N and 0 <= C < M and not visited[R][C]:
                visited[R][C] = 1  # 방문 체크를 미리 수행

                if maps[R][C] == '.':
                    q.append((R, C))
                elif maps[R][C] == '$':
                    ans += 1
                    q.append((R, C))
                    maps[R][C] = '.'
                elif 'a' <= maps[R][C] <= 'z':
                    q.append((R, C))
                    keys.add(maps[R][C])
                    new_key = maps[R][C].upper()
                    if new_key in needed_key_points:
                        for x, y in needed_key_points[new_key]:
                            q.append((x, y))
                        del needed_key_points[new_key]
                    maps[R][C] = '.'
                elif 'A' <= maps[R][C] <= 'Z':
                    if maps[R][C].lower() in keys:
                        q.append((R, C))
                        maps[R][C] = '.'
                    else:
                        needed_key_points[maps[R][C]].append((R, C))

    print(ans)

 

 

딕셔너리와 set을 이용하는것이 중요했다.

반응형