반응형
250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 사회조사분석사 2급 필기 요약정리
- 알고리즘
- 너비우선탐색
- 사회조사분석사 2급 접수
- 사회조사분석사 2급 필기 시험시간
- 오미크론 자가격리
- 사이킷런
- 사회조사분석사2급실기신청꿀팁
- 시물레이션
- DFS
- 공모주청약
- 사회조사분석사 2급 공부방법
- 사회조사분석사 2급 필기 공부방법
- 머신러닝
- 사회조사분석사 2급
- 공모주
- 백준
- 그리디
- 사회조사분석사 2급 독학
- BFS
- 현대엔지니어링
- 현대엔지니어링 수요예측
- 벽부수고이동하기 파이썬
- 2월공모주
- 백준 알고리즘
- 사회조사분석사 2급 기출문제집
- 파이썬 정렬
- 공모주 청약
- 정렬
- 사회조사분석사2급실기신청
Archives
- Today
- Total
세상을 바꾸는 데이터
[백준 16954번] 움직이는 미로 탈출 - 파이썬 본문
문제 링크:
https://www.acmicpc.net/problem/16954
풀이 유형:
그래프 이론, 그래프 탐색, 너비 우선 탐색
★문제풀이 Point★
1. 계속해서 이동하는 벽을 어떻게 추가하고 삭제하는지 고민 필요(set, pop, appendleft)
2. 캐릭터가 이동한 다음, 벽이 이동하는 순서로 진행
3. 너비 우선 탐색(bfs)으로 구현
풀이 과정:
이 문제는 욱제의 캐릭터가 가장 오른쪽 윗 칸으로 이동할 수 있는지 없는지 구해보는 문제이다.
bfs(너비 우선 탐색)으로 풀면 되는데, 벽을 어떻게 없애고 새로 생성하는지 고민을 해봐야 한다.
첫 번째 방법:
벽이 있는 위치를 집합으로 받고, 1초씩 지날 때마다 벽의 위치를 업데이트한다.
두 번째 방법:
맵에 있는 맨 마지막 행을 삭제하고, 맨 위 행에 빈칸으로 이루어진 행을 삽입한다.
첫 번째 방법이 두 번째 방법보다 변수와 조건문을 자주 사용하지 않은 측면에서 시간 복잡도와 메모리가 작은 코드로 나타났다.
풀이 코드:
첫 번째 방법: 벽이 있는 위치를 집합으로 받고, 1초씩 지날 때마다 벽의 위치를 업데이트
# 16954번 움직이는 미로 탈출
# 벽의 위치를 받아 해결
import sys
input = sys.stdin.readline
from collections import deque
# 맵 리스트, 벽 위치 집합, 정답 변수 생성
board, wall, answer = [input().rstrip() for _ in range(8)], set(), 0
# 벽 위치 추가
for i in range(8):
for j in range(8):
if board[i][j] == '#':
wall.add((i, j))
# 9가지 방향 정의
steps = [[0, 0], [-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]]
# 방문 표시 집합 생성
visited = set()
# 큐 정의
q = deque()
q.append((7, 0))
# 큐가 빌 때까지 반복
while q:
for _ in range(len(q)):
x, y = q.popleft()
# 현재 위치에 벽이 있다면 건너뛰기
if (x, y) in wall:
continue
# 현재 위치가 도착 지점이라면
if x == 0 and y == 7:
# 1이 정답
answer = 1
# 반복문 탈출
break
# 이동할 수 있는 모든 방향에 대하여
for dx, dy in steps:
nx = x + dx
ny = y + dy
# 조건을 만족한다면
if 0 <= nx <= 7 and 0 <= ny <= 7 and not (nx, ny) in visited and not (nx, ny) in wall:
# 방문 표시 추가
visited.add((nx, ny))
# 큐에 추가
q.append((nx, ny))
# 벽이 있다면 방문 표시 초기화
if wall:
visited = set()
# 다음 위치에 있는 벽 집합 생성
next_wall = set()
# 다음 벽의 위치 추가
for x, y in wall:
if x < 7:
next_wall.add((x+1, y))
# 벽 위치를 업데이트
wall = next_wall
print(answer)
두 번째 방법: 맵에 있는 맨 마지막 행을 삭제하고, 맨 위 행에 빈칸으로 이루어진 행을 삽입
# 16954번 움직이는 미로 탈출
# 1. 맵 입력받기
# 2. bfs 구현
from collections import deque
# bfs 함수 구현
def bfs():
# 시작 위치 삽입
q = deque([(7, 0)])
# 벽 이동 횟수
turn = 0
# 큐가 빌 때까지 반복
while q:
# 큐에 있는 위치 개수
len_q = len(q)
for _ in range(len_q):
# 행과 열 꺼내기
row, col = q.popleft()
# 시작 위치가 벽이라면 건너뛰기
if map[row][col] == '#':
continue
# 시작 위치가 도착 지점이면 1을 반환
if (row, col) == (0, 7):
return 1
# 9가지 이동 방향에 대하여
for i in range(9):
nx = row + dx[i]
ny = col + dy[i]
# 이동 위치가 맵을 벗어난다면
if not (0 <= nx <= 7 and 0 <= ny <= 7):
continue
# 이동 위치가 빈 곳이라면
if map[nx][ny] == '.':
q.append((nx, ny))
# 맵 가장 아래에 있는 행 삭제
map.pop()
# 맵 가장 위에 빈 칸으로 이루어진 행을 삽입
map.appendleft(['.', '.', '.', '.', '.', '.', '.', '.'])
# 벽 이동 횟수 추가
turn += 1
# 벽 이동 횟수가 9가 되면 모든 벽이 사라지므로
if turn == 9:
return 1
# 캐릭터가 더 이상 움직일 수 없다면 0을 반환
return 0
# 맵 입력받기
map = deque(list(input()) for _ in range(8))
# 캐릭터가 이동할 수 있는 방향: 정지, 상, 하, 좌, 우, 대각선(왼쪽 위, 오른쪽 위, 왼쪽 아래, 오른쪽 아래)
dx = [0, -1, 1, 0, 0, -1, -1, 1, 1]
dy = [0, 0, 0, -1, 1, -1, 1, -1, 1]
# bfs 함수 실행 후 정답 출력
print(bfs())
728x90
반응형
'PS Study > BOJ(백준)' 카테고리의 다른 글
[백준 17144번] 미세먼지 안녕! - 파이썬 (33) | 2022.03.08 |
---|---|
[백준 17427번] 약수의 합 2 - 파이썬 (30) | 2022.03.07 |
[백준 16235번] 나무 재태크 - 파이썬 (79) | 2022.03.04 |
[백준 16946번] 벽 부수고 이동하기 4 - 파이썬 (56) | 2022.03.01 |
[백준 2206번] 벽 부수고 이동하기 - 파이썬 (40) | 2022.02.28 |
Comments