728x90
반응형
*문제 출처는 백준에 있습니다.
문제 제목: 방탈출
문제 사이트: https://www.acmicpc.net/problem/23352
나의 풀이
세세한 방문처리 잘 봐야하고
임의의 방에서 출발한다는 것 -> 꼭 모서리 부분부터 출발하는것은 아님
나는 격자 테두리부분으로만 출발하는 줄 알았는데 아니드라
그리고 큐에 넣을 첫번째 노드 방문처리 확실하게 하기
길이가 같은 노드는 저장해뒀다가 나중에 문제 조건에서 의미하는것 잘 확인하고 출력
n,m 이거 위치도 제대로 봐야함 그대로 했다가 x,y 바뀌었음;;
import sys
from collections import deque
# 임의의 방에서 다른 방으로 이동할 때는 항상 두 방 사이의 최단 경로로 이동한다.
# 1번을 만족하는 경로 중 가장 긴 경로의 시작 방과 끝 방에 적힌 숫자의 합
# 만약 위 2가지 조건을 만족하는 경로가 여러 개라면,
# 시작 방과 끝 방에 적힌 숫자의 합이 가장 큰 값이 비밀번호가 된다.
# 시작 방과 끝 방은 동일한 위치일 수도 있다.
input = sys.stdin.readline
n, m = map(int,input().split()) # m 행 n 열
maps = []
for _ in range(m):
maps.append(list(map(int,input().split())))
def bfs(start):
visited = [[False] * n for _ in range(m)]
queue = deque([[start[0],start[1],0]])
visited[start[0]][start[1]] = True # 시작점 처리 제대로하기
pre = 0
end_point = start
while queue:
q = queue.popleft()
qy, qx, cnt = q
direct = ((-1, 0), (1, 0), (0, -1), (0, 1)) # 상 하 좌 우
for i in range(4):
dy, dx = direct[i]
y = qy + dy
x = qx + dx
if 0 <= y < m and 0 <= x < n and visited[y][x] == False and maps[y][x] != 0:
visited[y][x] = True
queue.append((y, x, cnt + 1))
if cnt + 1 > pre:
pre = cnt + 1
end_point = (y, x)
return pre, end_point
rooms = [(y, x) for y in range(m) for x in range(n) if maps[y][x] != 0]
max_cnt = float('-inf')
tmps = []
if rooms:
for start_point in rooms:
cnt, end_point = bfs(start_point)
if end_point:
path_sum = maps[start_point[0]][start_point[1]] + maps[end_point[0]][end_point[1]]
if cnt > max_cnt:
max_cnt = cnt
tmps = [(path_sum, cnt)]
elif cnt == max_cnt:
tmps.append((path_sum, cnt))
tmp = sorted([i for i in tmps if i[1] == max_cnt], reverse=True)
print(tmp[0][0])
else:
print(0)
근데 틀림 아오
나중에 다시 또풀어야지
25.04.01 재풀이
시작부분과 끝부분의 합이 커야한다는 조건이 중요하다.
아무리 bfs 를 구현잘해도 해당 조건을 무시하면 제대로 구현 안됨
visited 로 방문했던 노드들을 최장으로 만들어간다.
import sys
from collections import deque
input = sys.stdin.readline
N,M = map(int,input().split())
maps = []
for i in range(N):
maps.append(list(map(int,input().split())))
directions = ((0,1),(0,-1),(1,0),(-1,0))
def bfs(sy,sx):
queue = deque([[sy,sx]])
visited = [[-1] * M for _ in range(N)]
visited[sy][sx] = 0
max_sum = maps[sy][sx] * 2 # 시작방과 끝 방은 동일할 수 있다.
max_dist = 0
while queue:
qy,qx = queue.popleft()
for i in range(4):
ny = qy + directions[i][0]
nx = qx + directions[i][1]
if 0 <= ny < N and 0 <= nx < M and visited[ny][nx] == -1 and maps[ny][nx] != 0:
visited[ny][nx] = visited[qy][qx] + 1
queue.append([ny,nx])
if visited[ny][nx] > max_dist:
max_dist = visited[ny][nx]
max_sum = maps[sy][sx] + maps[ny][nx] # [페이크포인트] 시작 좌표와 가장 먼 거리(최장거리)에 위치한 좌표의 값의 합
elif visited[ny][nx] == max_dist:
max_sum = max(max_sum,maps[sy][sx] + maps[ny][nx]) # [페이크포인트] 시작 좌표와 가장 먼 거리(최장거리)에 위치한 좌표의 값의 합
return max_sum, max_dist
# 최장거리일때 max값 구하면됨
total_max_sum = 0
total_max_dist = 0
for i in range(N):
for j in range(M):
if maps[i][j] != 0:
sum_, dist_ = bfs(i,j)
if dist_ > total_max_dist:
total_max_dist = dist_
total_max_sum = sum_
elif dist_ == total_max_dist:
total_max_sum = max(sum_,total_max_sum)
print(total_max_sum)
최장거리일때, 합이 같으면 합이 큰것 확인하는 조건절도 제대로 확ㅇ니하자..........
꼭 한번 더 풀어봐야함
※ 알아야 할 것
- BFS에서 시작점 방문 체크 누락
visited[start] = True 처리를 안 해줘서 중복 방문 발생 가능성 있음
→ BFS에서는 시작점도 반드시 visited 처리해야 한다 - visited 방식 개선
기존에는 방문 여부를 True/False로만 저장했지만,
수정 후에는 **최단 거리를 저장하는 visited 배열 (visited[y][x] = 거리)**을 사용
→ 이 방식은 도달 거리 비교 및 조건 분기 처리에 더 유용하고 확장성 있음 - 조건에서 “임의의 방”이면 전체 방 순회를 기본으로 생각해야 함
728x90
반응형
'coding test - python > 백준' 카테고리의 다른 글
백준 / 1236번 성지키기 / Python 파이썬 (0) | 2025.04.02 |
---|---|
백준 / 14503번 로봇청소기 -bfs, 시뮬 / Python 파이썬 (1) | 2025.04.02 |
백준 / 14500번 테트로미노- 백트래킹, dfs / Python 파이썬 (0) | 2025.04.01 |
백준 / 1197번 최소 스패닝 트리 - 힙,해시 / Python 파이썬 (0) | 2025.03.30 |
백준 / 2578번 빙고 - 구현 / Python 파이썬 (3) | 2025.03.29 |