[백준] 2206 벽 부수고 이동하기 와 나의 시행착오들 기록

2022. 2. 4. 13:15·Algorithm (PS)
728x90

최단거리 찾는 문제인데 벽하나 부술수있다는 게 특이점이다 

풀이 1 :시간초과가 났다 이중포문으로 백트래킹은 무리였던건가 ㄱ- 파이썬만 그런지 c++도 그런지 궁금하다 진짜 

이 경우, 내가 가는 경로 중에 벽이 있는지 상관없이, 모든 벽을 한번씩 다 없애보는 코드인데, 효율성을 높이려면 내가 가는 경로 도중에 마주친 벽을 제거해야 할 것 같다..

from collections import deque

n, m = map(int, input().split())
graph = [list(map(int, input())) for _ in range(n)]
INF = int(1e9)
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def bfs(): # 최단 경로 구하기
    dist = [[-1] * m for _ in range(n)]
    q = deque()
    q.append((0, 0))
    dist[0][0] = 1
    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 dist[nx][ny] == -1 and graph[nx][ny] == 0:
                dist[nx][ny] = dist[x][y] + 1
                q.append((nx, ny))

    return dist[n-1][m-1]

result = INF
for i in range(n):
    for j in range(m):
        if graph[i][j] == 1:
            graph[i][j] = 0
            temp = bfs()
            if temp != -1:
                result = min(result, temp)
            graph[i][j] = 1


if result == INF:
    print(-1)
else:
    print(result)

 

풀이 2: 

벽 부순 상태를 저장하는 표를 따로 만든 경우 

from collections import deque

n, m = map(int, input().split())
graph = [list(map(int, input())) for _ in range(n)]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def bfs(): # 최단 경로 구하기
    check = [[False] * m for _ in range(n)] # 벽 부수기를 했는지 확인
    dist = [[-1] * m for _ in range(n)] # 최단거리

    q = deque()
    q.append((0, 0))
    dist[0][0] = 1
    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 dist[nx][ny] == -1:
                if graph[nx][ny] == 0:
                    dist[nx][ny] = dist[x][y] + 1
                    q.append((nx, ny))
                if graph[nx][ny] == 1 and check[x][y] == False:
                    check[nx][ny] = True
                    dist[nx][ny] = dist[x][y] + 1
                    q.append((nx, ny))

    print(dist)
    return dist[n-1][m-1]


temp = bfs()
print(temp)

그런데 이 방법도 오류가 있다 ;; 나는 좌표 x, y 까지 오기까지 벽을 부순적이 있는지 없는지를 저장하고, 벽을 부순 적이 없다면 nx, ny로 새롭게 이동할 때 벽을 부셔도 된다라고 가정했다 

그러나 결국 벽을 부순 후의 최종 결과와 벽을 부수지 않은 후의 결과를 비교해야 하는데, 두 값을 모두 가지고 있어야 한다. 나는 벽을 부수지 않았을 때의 결과를 가지고 있지 않은 것이다 

따라서 dist에 축 하나를 더 만들어 주어야 한다. 

https://www.acmicpc.net/board/view/81375 

질문 게시판의 답변을 좀 참고 했다 나랑 비슷한 고민을 하시는 분이 있어서 ㅎㅎ 

 

글 읽기 - 왜 틀렸는지 잘 모르겠습니다. 알려주세요ㅠㅠ

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

 

풀이 3 : 벽을 부수는 상태도 같이 저장해준다 ! 

 

from collections import deque

n, m = map(int, input().split())
graph = [list(map(int, input())) for _ in range(n)]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def bfs(): # 최단 경로 구하기
    dist = [[[-1]*2 for _ in range(m)] for _ in range(n)]
    q = deque()
    q.append((0, 0, 0)) # x, y, crash
    dist[0][0][0] = 1 # 최단 거리
    while q:
        x, y, crash = q.popleft()
        if x == n-1 and y == m-1:
            return dist[x][y][crash]
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if graph[nx][ny] == 0 and dist[nx][ny][crash] == -1:
                    dist[nx][ny][crash] = dist[x][y][crash] + 1
                    q.append((nx, ny, crash))
                if graph[nx][ny] == 1 and crash == 0:
                    dist[nx][ny][crash +1] = dist[x][y][crash] + 1
                    q.append((nx, ny, crash+1))
    return -1

print(bfs())

후후 어렵군 

728x90

'Algorithm (PS)' 카테고리의 다른 글

[백준] 2225 합분해 in Python <점화식을 테이블을 그리면 쉽게 구하는 DP문제>  (0) 2022.02.05
[백준] 2178 미로탐색 (BFS 풀이)  (0) 2022.02.05
[백준] 12865 평범한 배낭, Knapsack Problem  (0) 2022.02.03
[프로그래머스] 크레인 인형 뽑기  (0) 2022.02.03
[백준/삼성] 16236 아기상어  (0) 2022.02.03
'Algorithm (PS)' 카테고리의 다른 글
  • [백준] 2225 합분해 in Python <점화식을 테이블을 그리면 쉽게 구하는 DP문제>
  • [백준] 2178 미로탐색 (BFS 풀이)
  • [백준] 12865 평범한 배낭, Knapsack Problem
  • [프로그래머스] 크레인 인형 뽑기
minjiwoo
minjiwoo
Data Engineering과 Cloud Native 기술에 대해 Dive Deep 하는 플랫폼 엔지니어가 되는 것을 목표로 하고 있습니다. 경험과 공부한 내용을 기록하며 지속가능한 엔지니어가 되는 것이 꿈입니다.
minjiwoo
minji's engineering note
minjiwoo
전체
오늘
어제
  • 분류 전체보기 (613)
    • Data Engineering (42)
      • Apache Spark (11)
      • Databricks & Delta Lake (9)
      • Airflow (3)
      • SQL (6)
      • Trouble Shooting (2)
      • Hadoop (2)
      • MLOps (1)
    • Cloud Engineering (104)
      • AWS (23)
      • Linux 🐧 (29)
      • Docker 🐳 (21)
      • Kubernetes ⚙️ (20)
      • Ansible (10)
    • Computer Science (87)
      • 네트워크 (9)
      • 운영체제 (25)
      • 정보처리기사 (48)
      • CS 기술 면접 스터디 (3)
    • Programming Languages (27)
      • Python (17)
      • C와 C++ (10)
    • Backend (5)
      • Django (2)
    • 프로젝트 (2)
      • 테크포임팩트 (2)
    • iOS (11)
      • 레이블러리 (2)
    • Algorithm (PS) (275)
      • LeetCode (6)
    • 개발일기 (30)
      • 내돈내산 후기🎮 (3)
      • 개발자 취준생 (5)
      • Today I Learned (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • Hi there

인기 글

태그

  • Swift
  • 쿠버네티스
  • 카카오코딩테스트
  • 알고리즘
  • Kubernetes
  • BFS
  • docker
  • 데이터엔지니어링
  • linux
  • Leetcode
  • SPARK
  • EC2
  • 코딩테스트
  • 클라우드
  • dp
  • 리눅스
  • 백트래킹
  • ansible
  • 빅데이터
  • python
  • 데이터엔지니어
  • 프로그래머스
  • 스파크
  • 파이썬
  • 운영체제
  • AWS
  • dfs
  • 백준
  • Databricks
  • 데이터브릭스

최근 댓글

최근 글

hELLO· Designed By정상우.v4.5.2
minjiwoo
[백준] 2206 벽 부수고 이동하기 와 나의 시행착오들 기록
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.