파이썬 알고리즘 063 | 미로의 최단거리 통로(BFS 활용)**

Yunny.Log ·2021년 1월 20일
0

Algorithm

목록 보기
63/318
post-thumbnail

63. 미로의 최단거리 통로(BFS 활용)

7x7 격자판 미로를 탈출하는 최단경로의 경로수를 출력하는 프로그램을 작성하세요. 경로수는 출발점에서 도착점까지 가는데 이동한 횟수를 의미한다. 출발점은 격자의 (1, 1) 좌표이고, 탈출 도착점은 (7, 7)좌표이다. 격자판의 1은 벽이고, 0은 도로이다.
격자판의 움직임은 상하좌우로만 움직인다. 미로가 다음과 같다면

위와 같은 경로가 최단 경로이며 경로수는 12이다.
▣ 입력설명
7*7 격자판의 정보가 주어집니다.
▣ 출력설명
첫 번째 줄에 최단으로 움직인 칸의 수를 출력한다. 도착할 수 없으면 -1를 출력한다.
▣ 입력예제 1
0 0 0 0 0 0 0
0 1 1 1 1 1 0
0 0 0 1 0 0 0
1 1 0 1 0 1 1
1 1 0 1 0 0 0
1 0 0 0 1 0 0
1 0 1 0 0 0 0
▣ 출력예제 1
12

<내 풀이>

사고방식은 비슷하게 했는데 그걸 어떻게 구현해야 할 지를 모르겠음
밑에와 같이 나름 구현을 해보았는데 q가 empty하다고만 나온다......


from collections import deque
a=[list(map(int, input().split())) for _ in range(7)]
dx=[-1,0,1,0]
dy=[0,1,0,-1]
ch=[[0]*7 for _ in range(7)]
ch[1][1]
q=deque()
q.append((0,0))
level=0

while True:
    k=q.popleft()
    if k==(6,6):
        break
    for i in range(4) :
        x=k[0]+dx[i]
        y=k[1]+dy[i]
        if x!=0 and y!=0 :
            if ch[x][y]==0 :
                ch[x][y]=1
                q.append((x,y))
    level+=1
print(level)

<풀이>


from collections import deque
dx=[-1, 0, 1, 0]
dy=[0, 1, 0, -1]
a=[list(map(int, input().split())) for _ in range(7)]
ch=[[0]*7 for _ in range(7)] #몇번째 방문인 지 확인해주는 애
Q=deque()
Q.append((0, 0))
a[0][0]=1 #처음 출발값에 1 넣어줌으로써 벽처리 해준 것
while Q:
    tmp=Q.popleft()
    for i in range(4):
        x=tmp[0]+dx[i]
        y=tmp[1]+dy[i]
        if 0<=x<=6 and 0<=y<=6 and a[x][y]==0: #x,y 둘다 0부터 6사이 범위에 있어야 하고 벽이 아니어야 하므로
            a[x][y]=1 #이제 왔으면 얘는 벽으로 처리해줘야 함
            ch[x][y]=ch[tmp[0]][tmp[1]]+1 #몇번째에 방문했는지 갱신
            Q.append((x, y))
if ch[6][6]==0: # [6][6]이 끝난 뒤에도 그대로 0이라면 못왔다는 얘기
    print(-1)
else:
    print(ch[6][6])

<반성점>

  • 조건을 잘못 세움, 그리고 부족하게 세운 부분도 有
    (x,y가 0이 아니라고 했는데 0도 가능하고 6까지 라는 조건도 세웠어야 함)
  • 문제에서 (1,1) , (7,7)이라고 제시됐더라도 혹하지 말고 의미하는 바가 뭔지 6,6으로 생각해도 이상이 없는지 검토해야 됨
    그냥 주어진 대로 0~6 이라고 생각하고 풀면 됨

<배운 점>

  • 0인 것들을 만나서 경로로 삼을 수 있게 되면 다시는 못 돌아가게
    거기를 1로 바꿔준다(벽으로 바꿔준다) => 그 다음에 몇번 째에 왔는지 카운팅 해주는 리스트를 만들어서 부모보다 1 더해주면 된다

  • 최단 거리는 무조건 BFS로 풀어라

  • 자주 나오는 것

(1) 0리스트 : ch=[[0]*7 for _ in range(7)]

(2) 2차원 리스트 받아주기 : a=[list(map(int, input().split())) for _ in range(n)]

<2차 내 풀이> - 실패

=> a를 ch삼으려고 시도해서 ch를 안 만들었던 건데,
그러면 부족함, 몇번째에 도착했는지 알려줄 ch를 항상 최단 거리 문제가 나올 때마다 넣어주도록 하자

  • 들렸던 곳은 벽처리 해주기
  • 또 처음에 q에 출발점 넣어줄 때 0,0 넣어야 하는데 문제에서 0,0이라고 했다고 자꾸 착각한다 냉정하게 출발점은 0,0이다
  • 그리고 출발점으로 돌아가면 안되니깐 지나가면 벽처리 해주는 a에서 출발점은 1(벽)으로 바꿔준다 (a[0][0]=1)
 
from collections import deque
a=[list(map(int,input().split())) for _ in range(7)]
q=deque()
q.append((1,1))
a[1][1]=1
cnt=0
dx=[-1,0,1,0]
dy=[0,1,0,-1]
while q : 
    cnt+=1
    k=q.popleft()
    for i in range(4) :
        x=k[0]+dx[i]
        y=k[1]+dy[i]
        if 0<=x<7 and 0<=y<7 and a[x][y]==0:
            a[x][y]=1
            print(a)
            q.append((x,y))
    cnt+=1
if a[6][6]==1:
    print(cnt)
else :
    print('-1')

=> 수정 후 풀이


from collections import deque
a=[list(map(int,input().split())) for _ in range(7)]
q=deque()
q.append((0,0)) #q에다가 처음엔 1,1 넣는게 아니라 출발점을 넣어줘야 한다. 문제에서는 1,1이라 나와잇지만 출발점은 사실0,0이니깐..
ch=[[0]*(7) for _ in range(7)] #얘는 몇번째에 도착한 건지 판별해줄 아이
a[0][0]=1 #출발점을 0으로 해주기, 출발점으로 다시 돌아가면 안되니깐 벽처리해주기
dx=[-1,0,1,0]
dy=[0,1,0,-1]
while q : 
    k=q.popleft()
    for i in range(4) :
        x=k[0]+dx[i]
        y=k[1]+dy[i]
        if 0<=x<7 and 0<=y<7 and a[x][y]==0: 
            a[x][y]=1
            ch[x][y]=(ch[k[0]][k[1]])+1
            q.append((x,y))
if ch[6][6]==0: #도착점에 도달하지 못한 것
    print('-1')
else : #도착점에 도달해서 값 매겨졌을 때
    print(ch[6][6])
    

0개의 댓글