/ 제출 1 / ( 소요 시간 : 30분 )
import sys
input = sys.stdin.readline
from collections import deque
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
n, m = map(int, input().split())
board = []
walls = []
for i in range(n):
line = list(map(int, input().strip()))
for j in range(m):
if line[j] == 1:
walls.append((i, j))
board.append(line)
result = []
for wall in walls:
i, j = wall
board[i][j] = 0
q = deque([(0, 0)])
while q:
x, y = q.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < n and 0 <= ny < m and board[nx][ny] == 0:
board[nx][ny] = board[x][y] + 1
q.append((nx, ny))
if board[n-1][m-1] != 0:
result.append(board[n-1][m-1]+1)
else:
result.append(-1)
print(min(result))
21퍼센트 채점하고 틀렸습니다가 뜬다. 일부 테케는 맞춘다는건데.. 어디서 오류가 있는걸까. 빠르게 찾아보겠다.
: 아 이건 왜인지 알겠네요. result에 -1을 넣고, 마지막에 min값으로 결과를 빼줬으니 사실 -1이 나올 확률도 있고,
: board자체를 수정해서 첫 계산 이후에는 다시 원래대로의 board값이 아닌 전혀 다른 모양을 가지고 계산을 하게 되는 모양새입니다.
: 따라서 visited를 매번 따로 두어 그것을 계산하게 했는데요.
/ 제출 2 / ( 소요 시간 : 이전 제출 +15분 )
import sys
input = sys.stdin.readline
from collections import deque
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
n, m = map(int, input().split())
board = []
walls = []
for i in range(n):
line = list(map(int, input().strip()))
for j in range(m):
if line[j] == 1:
walls.append((i, j))
board.append(line)
result = []
for wall in walls:
visited = [[0] * m for _ in range(n)]
a, b = wall
board[a][b] = 0
visited[0][0] = 1
q = deque([(0, 0)])
while q:
x, y = q.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < n and 0 <= ny < m and board[nx][ny] == 0 and visited[nx][ny] == 0:
visited[nx][ny] = visited[x][y] + 1
q.append((nx, ny))
if visited[n-1][m-1] != 0:
result.append(visited[n-1][m-1])
board[a][b] = 1
if result:
print(min(result))
else:
print(-1)
이건 또 시간초과가 납니다. ㅎ
그럴만도 한게 visited를 최악 1000*1000하는 계산을 벽의 개수만큼 하니, 벽이 1000개 가깝다면 1000^3번 연산하게 됩니다. 여기에 본연산을 또 더한다면 정말 성능이 떨어집니다.
https://hongcoding.tistory.com/18
[백준] 2206 벽 부수고 이동하기 (Python 파이썬)
문제 설명 www.acmicpc.net/problem/2206 2206번: 벽 부수고 이동하기 N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1,
hongcoding.tistory.com
https://seongonion.tistory.com/m/107
[백준] 2206번 벽 부수고 이동하기 - 파이썬(Python)
문제 (링크) https://www.acmicpc.net/problem/2206 2206번: 벽 부수고 이동하기 N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당
seongonion.tistory.com
어우 친절한 설명 굿..
/ 제출 2 /
import sys
input = sys.stdin.readline
from collections import deque
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
n, m = map(int, input().split())
board = []
for i in range(n):
line = list(map(int, input().strip()))
board.append(line)
def bfs():
visited = [[[0] * 2 for _ in range(m)] for _ in range(n)]
visited[0][0][0] = 1
q = deque([(0, 0, 0)])
while q:
x, y, w = q.popleft()
if x == n - 1 and y == m - 1:
return visited[x][y][w]
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < n and 0 <= ny < m:
# 현재 위치로 이동 가능하고, 아직 방문도 안 했다면
if board[nx][ny] == 0 and visited[nx][ny][w] == 0:
visited[nx][ny][w] = visited[x][y][w] + 1
q.append([nx, ny, w])
# 현재 위치가 벽이고, 아직 지금까지 부수지 않았다면(nx,ny이전에 x,y의 상태가 0인 경우)
if board[nx][ny] == 1 and w == 0:
visited[nx][ny][w+1] = visited[x][y][w] + 1
q.append([nx, ny, w+1])
# q돌면서 목표지점 나와서 리턴하는게 불가능한 상태니까 -1리텅ㄴ
return -1
print(bfs())
: 이러면 배열을 하나 더 썼을 뿐이지 기존 BFS코드에서 시간복잡도를 한 사이클 더 돌리게 되지 않는다. 그래서 시간 내로 연산이 가능해진 것.
'CodingTest > Baekjun Online Judge' 카테고리의 다른 글
[ BOJ / 파이썬 ] 2573 빙산 (0) | 2022.08.20 |
---|---|
[ BOJ / 파이썬 ] 9466 텀 프로젝트 (0) | 2022.08.19 |
[ BOJ / 파이썬 ] 2574 불 (0) | 2022.08.17 |
[ BOJ / 파이썬 ] 7562 나이트의 이동 (0) | 2022.08.17 |
[ BOJ / 파이썬 ] 7569 토마토 (0) | 2022.08.16 |