ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [DFS/BFS] 아이템 줍기 (파이썬) - 진행 중
    코딩 테스트/프로그래머스 2023. 6. 13. 15:15

    문제 설명

    https://school.programmers.co.kr/learn/courses/30/lessons/87694

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

    문제 풀이

    • gr에는 직사각형들의 변에 해당하는 좌표들에 넘버를 달아줌. (0번째 rec면 그 변 좌표들에 gr[x][y].append(0) )
    • inner 라는 그래프를 따로 만들어서 해당 직사각형안에 있는 모든 좌표들에 True값을 부여해줌 
      1. 현재 위치 x,y 의 직사각형 넘버를 따온다.
      2. 다음으로 이동 할 수 있는 nx,ny 의 gr값(직사각형 넘버)이 이전 x,y에서의 넘버와 같고 gr의 길이가 1이라면 해당 직사각형의 같은 변을 타고 있으므로 큐에 담아주면 됨.
      3. 만약 gr[nx][ny]의 길이가 2 이상이라면, 다른 직사각형이 껴들어서 갈라지는 부분인 것이므로 조건문을 통해 테두리 바깥으로 이동하게끔 잡아줘야 함.
        • 변이 갈라지는 (x,y) => (nx,ny) 로 이동 했다면 큐에는 이 점은 변이 갈라지는 꼭지점이라는 것을 알려줄 dot값 1과 어떤 직사각형을 타고 왔는지 넘버를 알려줄 pre에 넘버를 담아줌.
          • q ( 꼭지점의 gr[nx][ny] 넘버, nx,ny, 1, pre 넘버 )
          • gr[nx][ny]넘버는 pre 넘버와 겹치면 안되므로 for문을 통해서 걸러주면 됨
        • 이후 큐에서 이 요소를 꺼낸 후 ( 변이 갈라지는 꼭지점 요소, dot==1 ) 직사각형이 겹쳐지는 부분(내부)은 inner 그래프를 통해 거를 수 있음.
        • 만약 현재 새로운 직사각형 넘버가 3이고 이전 넘버가 2인 직사각형에서 왔다면 내부로 겹쳐지는 inner[nx][ny][2] == True 인 좌표는 방문하면 안됨. 
          • 이 때, 다음 좌표도 꼭지점이 될 수 있으므로 이 점도 gr[nx][ny]의 길이가 2이상 인 것으로 판별해서 넣어줌
      4. 만약 첫 출발 지점이 꼭지점 일 경우도 위와 동일한 로직으로 출발 지점을 잡아주면 됨 ( 이렇게까지 했을 때 100점 만점 중 76 점 받음 )

    소스 코드

    오답 노트

    • 예제에 제시된 테케를 고려해서 코드를 짬 ( 70.0 / 100 ) 
    • 출발 지점이 변에 의해 갈라지는 부분인지 아닌지 고려해서 코드를 짜봄 ( 76.4 / 100 )  
    from collections import deque
    
    
    def solution(rec, chx, chy, ix, iy):
        dx = [0,0,-1,1]
        dy = [-1,1,0,0]
        INF = int(1e9)
        answer = INF
        gr=[[[] for j in range(51)] for i in range(51)]
        inner = [[[False]*len(rec) for i in range(51)]for j in range(51)]
        for i in range(len(rec)):
            ax,ay=rec[i][0],rec[i][1]
            cx,cy=rec[i][2],rec[i][3]
            for j in range(ay,cy+1):
                gr[ax][j].append(i)
                gr[cx][j].append(i)
            for j in range(ax+1,cx):
                gr[j][ay].append(i)
                gr[j][cy].append(i)
            for j in range(ax,cx+1):
                for k in range(ay,cy+1):
                    inner[j][k][i]=True
    
        visited = [[INF]*51 for i in range(51)]
        visited[chx][chy]=0
        q = deque()
        if len(gr[chx][chy])==1:
            q.append((gr[chx][chy][0],chx,chy,-1,gr[chx][chy][0]))
        else:
            for cur in gr[chx][chy]:
                for a in gr[chx][chy]:
                    if a!=cur:
                        other=a
                for i in range(4):
                    ccx=chx+dx[i]
                    ccy=chy+dy[i]
                    if ccx<=0 or ccy<=0 or ccx>50 or ccy>50:
                        continue
                    if gr[ccx][ccy]==[]:
                        continue
                    if inner[ccx][ccy][other]==True:
                        continue
    
                    if len(gr[ccx][ccy])==1 and gr[ccx][ccy][0]==cur:
                        q.append((cur,ccx,ccy,-1,cur))
                        visited[ccx][ccy]=1
                    
                    if len(gr[ccx][ccy])>=2:
                        for j in gr[ccx][ccy]:
                            if j==cur:
                                continue
                            q.append((j,ccx,ccy,1,cur))
                            visited[ccx][ccy]=1
    
                    
                    
    
        while(q):
            cur, x,y,dot,pre = q.popleft()
            # print("cur:",cur,"   x:",x,"  y:",y,"  dot:",dot,"   pre: ",pre)
            # print(visited[x][y])
            # print("==================")
            if [x,y]==[ix,iy]:
                answer=min(answer,visited[x][y])
                continue
                
            for i in range(4):
                nx = x + dx[i]
                ny = y + dy[i]
                if nx<=0 or ny<=0 or nx>50 or ny>50:
                    continue
                if gr[nx][ny]==[]:
                    continue
                if visited[nx][ny]<visited[x][y]+1:
                    continue
                
                if dot==1:
                    if inner[nx][ny][pre]==False:
                        if len(gr[nx][ny])>=2:
                            for j in gr[nx][ny]:
                                if j==cur:
                                    continue
                                q.append((j,nx,ny,1,cur))
                                visited[nx][ny]=visited[x][y]+1
                        else:
                            q.append((cur,nx,ny,-1,cur))
                            visited[nx][ny]=visited[x][y]+1
                else:
                    if len(gr[nx][ny])==1 and gr[nx][ny][0]==cur:
                        q.append((cur,nx,ny,-1,cur))
                        visited[nx][ny]=visited[x][y]+1
    
                    if len(gr[nx][ny])>=2:
                        for j in gr[nx][ny]:
                            if j==cur:
                                continue
                            q.append((j,nx,ny,1,cur))
                            visited[nx][ny]=visited[x][y]+1
                
        return answer
    
    print(solution([[1,1,7,4],[3,2,5,5],[4,3,6,9],[2,6,8,8]],3,4,7,8))
Designed by Tistory.