ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Programmers] 거리두기 ν™•μΈν•˜κΈ° with Python
    PS 2021. 8. 29. 01:57
    728x90
    λ°˜μ‘ν˜•

    πŸ“Œ Programmers - [ 거리두기 ν™•μΈν•˜κΈ° ]

    πŸ’‘ 쑰건 및 풀이

    1. λŒ€κΈ°μ‹€μ— μ‘μ‹œμžλ“€μ΄ 면접을 μœ„ν•΄ λŒ€κΈ°λ₯Ό ν•˜κ³  μžˆλ‹€. λŒ€κΈ°μ‹€μ— μžˆλŠ” λŒ€κΈ°μžλ“€μ΄ 거리 두기λ₯Ό 잘 지킀고 μžˆμ„κΉŒ?
    2. λŒ€κΈ°μ‹€μ€ 5개, 각 λŒ€κΈ°μ‹€μ€ 5 * 5의 ν¬κΈ°μž…λ‹ˆλ‹€.
    3. μ‘μ‹œμžλ“€ κ°„μ˜ κ±°λ¦¬λŠ” λ§¨ν•΄νŠΌ κ±°λ¦¬λŠ” 2 μ΄ν•˜λ‘œ 앉을 수 μ—†μœΌλ‹ˆ 3 μ΄μƒμ΄μ–΄μ•Όν•œλ‹€.
    4. λ§¨ν•΄νŠΌ 거리가 2μ΄ν•˜μ—¬λ„ μ‘μ‹œμž 사이에 νŒŒν‹°μ…˜μœΌλ‘œ λ§‰ν˜€ 있으며 μ§€λ‚˜κ°ˆ λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ μ‘μ‹œμžλ‘œμ˜ κ²½λ‘œκ°€ μ—†λ‹€λ©΄ 상관이 μ—†λ‹€.
    5. BFS μœ ν˜•μ˜ 문제
    6. 두 ν…Œμ΄λΈ” T1, T2κ°€ ν–‰λ ¬ (r1, c1), (r2, c2)에 각각 μœ„μΉ˜ν•˜κ³  μžˆλ‹€λ©΄,
      T1, T2 μ‚¬μ΄μ˜ λ§¨ν•΄νŠΌ κ±°λ¦¬λŠ” |r1 - r2| + |c1 - c2|
    7. μ‘μ‹œμž, ν…Œμ΄λΈ”, νŒŒν‹°μ…˜ = P, O, X
    8. μ •ν™•μ„± ν…ŒμŠ€νŠΈμ˜ μ‹œκ°„μ€ 10초.

    πŸ–₯ μ†ŒμŠ€ μ½”λ“œ

    from collections import deque
    
    dx, dy = [1, -1, 0, 0], [0, 0, -1, 1]
    
    
    def bfs(board, now, goal, dist):
        q = deque()
        visited = []
        x, y = now
        q.append((0, x, y, []))
        visited.append(now)
        check = False
    
        while q:
            cost, x, y, visit = q.popleft()
    
            # 움직인 거리가 λ§¨ν—€νŠΌ 거리보닀 많으면 λ„˜μ–΄κ°€κΈ°
            if cost > dist:
                continue
    
            if (x, y) == goal:
                for i, j in visit:
                    if board[i][j] == 'X':
                        check = True
                    elif board[i][j] == 'O':
                        return False
    
            for i in range(4):
                nx, ny = dx[i] + x, y + dy[i]
                if -1 < nx < 5 and -1 < ny < 5:
                    if (nx, ny) not in visited:
                        # λͺ©ν‘œ 지점을 visited 에 넣지 μ•ŠλŠ”λ‹€.
                        # κ°€λŠ₯ν•œ λ§Žμ€ 경둜λ₯Ό 염두에 두어 κ³„μ‚°ν•œλ‹€.
                        if (nx, ny) != goal:
                            visited.append((nx, ny))
                        temp = visit[:]
                        temp.append((nx, ny))
                        q.append((cost + 1, nx, ny, temp))
        return check
    
    
    def solution(places):
        answer = []
    
        for i in range(len(places)):
            board = []
            data = places[i]
    
            ps = []
    
            # λŒ€κΈ°μ‹€ 리슀트 λ§Œλ“€κΈ°
            for j in range(5):
                for k in range(5):
                    if data[j][k] == 'P':
                        ps.append((j, k))
                board.append(list(data[j]))
    
            ps.sort()
            check = True
            for j in range(len(ps)):
                x1, y1 = ps[j]
                for k in range(j + 1, len(ps)):
                    x2, y2 = ps[k]
                    dist = abs(x1 - x2) + abs(y1 - y2)
                    if dist < 3:
                        if not bfs(board, ps[j], ps[k], dist):
                            check = False
                            break
                if not check:
                    break
    
            answer.append(1) if check else answer.append(0)
    
        return answer

    πŸ”– 예제 및 μ‹€ν–‰κ²°κ³Ό

    예제

    places = [["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"], ["POOPX", "OXPXP", "PXXXO", "OXXXO", "OOOPP"], ["PXOPX", "OXOXP", "OXPOX", "OXXOP", "PXPOX"], ["OOOXX", "XOOOX", "OOOXX", "OXOOX", "OOOOO"], ["PXPXP", "XPXPX", "PXPXP", "XPXPX", "PXPXP"]]

    μ‹€ν–‰κ²°κ³Ό

    [1, 0, 1, 1, 1]

    ⌨️ 문제 풀이

    1. μ •ν™•μ„± ν…ŒμŠ€νŠΈκ°€ 있기 λ•Œλ¬Έμ— μ‹œκ°„μ΄ˆκ³Ό 및 λ©”λͺ¨λ¦¬ μ΄ˆκ³Όμ— 신경을 μ¨μ•Όν•œλ‹€.
      κ·ΈλŸ¬λ―€λ‘œ μ‘μ‹œμžλ“€μ˜ μ’Œν‘œλ§Œ λ”°λ‘œ λ°°μ—΄λ‘œ λ°›μ•„μ„œ λ§¨ν•΄νŠΌ 거리λ₯Ό κ΅¬ν•œ λ’€ λ§¨ν•΄νŠΌ 거리가 2 μ΄ν•˜μΈ κ²ƒλ“€λ§Œ BFSλ₯Ό 톡해
      μ‘μ‹œμž 사이가 νŒŒν‹°μ…˜μœΌλ‘œ λ§‰ν˜€ μžˆλŠ”μ§€ ν™•μΈν•œλ‹€.
    2. λŒ€κΈ°μ‹€μ„ BFS둜 λŒλ©΄μ„œ 큐에 이동 거리, μ’Œν‘œ, 움직인 이동 μ’Œν‘œλ₯Ό λ°°μ—΄λ‘œ λ„£μ–΄ μ£Όλ©°,
      이동 거리가 λ§¨ν•΄νŠΌ 거리보닀 λ©€λ‹€λ©΄ BFS 과정을 skip ν•œλ‹€.
    3. 두 μ‘μ‹œμžμ˜ λ§¨ν•΄νŠΌ 거리가 2 μ΄ν•˜μΌ λ•Œ, 사이에 νŒŒν‹°μ…˜μ΄ μžˆλŠ” 경우λ₯Ό 처리 ν•˜μ§€ λͺ»ν•΄μ„œ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ 5번이 ν‹€λ Έλ‹€.
      λ‚΄κ°€ ν‹€λ¦° λ°˜λ‘€λŠ” μ•„λž˜μ™€ κ°™λ‹€. 닡은 1이닀.
      [["OPXPO", "OOOOO", "OOOOO", "OOOOO", "OOOOO"]]   

    πŸ’Ύ λŠλ‚€μ 

    • μ–΄μ œ ν’€μ—ˆλ˜ 뢈! 보닀 쉬웠닀.
    • λ°˜λ‘€ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ₯Ό μ°ΎλŠ”λ° 쑰금 어렀움이 μžˆμ—ˆλ‹€.
    • BFSλŠ” 짜기 λ‚˜λ¦„μΈ 것 κ°™λ‹€. queue 에 λ„£λŠ” 정보λ₯Ό λ‹€μ–‘ν•˜κ²Œ μ‚¬μš©ν•˜λŠ” 법이 μ΅μˆ™ν•΄μ§€κ³  μžˆλŠ” 것 κ°™μ•„ μ’‹λ‹€.
      κ·ΈλŸ¬λ‚˜ visited 배열을 더 λ‹€μ–‘ν•˜κ²Œ μ‚¬μš©ν•˜λŠ” 법을 μ—°μŠ΅ν•΄μ•Όκ² λ‹€.
    λ°˜μ‘ν˜•

    λŒ“κΈ€

Designed by Tistory.