[level 2] 거리두기 확인하기 - 81302
성능 요약
메모리: 10.2 MB, 시간: 0.17 ms
구분
코딩테스트 연습 > 2021 카카오 채용연계형 인턴십
채점결과
정확성: 100.0
합계: 100.0 / 100.0
제출 일자
2024년 04월 21일 22:21:28
문제 설명
개발자를 희망하는 죠르디가 카카오에 면접을 보러 왔습니다.
코로나 바이러스 감염 예방을 위해 응시자들은 거리를 둬서 대기를 해야하는데 개발 직군 면접인 만큼
아래와 같은 규칙으로 대기실에 거리를 두고 앉도록 안내하고 있습니다.
- 대기실은 5개이며, 각 대기실은 5x5 크기입니다.
- 거리두기를 위하여 응시자들 끼리는 맨해튼 거리1가 2 이하로 앉지 말아 주세요.
- 단 응시자가 앉아있는 자리 사이가 파티션으로 막혀 있을 경우에는 허용합니다.
예를 들어,
![]() |
![]() |
![]() |
---|---|---|
위 그림처럼 자리 사이에 파티션이 존재한다면 맨해튼 거리가 2여도 거리두기를 지킨 것입니다. | 위 그림처럼 파티션을 사이에 두고 앉은 경우도 거리두기를 지킨 것입니다. | 위 그림처럼 자리 사이가 맨해튼 거리 2이고 사이에 빈 테이블이 있는 경우는 거리두기를 지키지 않은 것입니다. |
![]() |
![]() |
![]() |
응시자가 앉아있는 자리(P )를 의미합니다. |
빈 테이블(O )을 의미합니다. |
파티션(X )을 의미합니다. |
5개의 대기실을 본 죠르디는 각 대기실에서 응시자들이 거리두기를 잘 기키고 있는지 알고 싶어졌습니다. 자리에 앉아있는 응시자들의 정보와 대기실 구조를 대기실별로 담은 2차원 문자열 배열 places
가 매개변수로 주어집니다. 각 대기실별로 거리두기를 지키고 있으면 1을, 한 명이라도 지키지 않고 있으면 0을 배열에 담아 return 하도록 solution 함수를 완성해 주세요.
제한사항
places
의 행 길이(대기실 개수) = 5places
의 각 행은 하나의 대기실 구조를 나타냅니다.
places
의 열 길이(대기실 세로 길이) = 5places
의 원소는P
,O
,X
로 이루어진 문자열입니다.places
원소의 길이(대기실 가로 길이) = 5P
는 응시자가 앉아있는 자리를 의미합니다.O
는 빈 테이블을 의미합니다.X
는 파티션을 의미합니다.
- 입력으로 주어지는 5개 대기실의 크기는 모두 5x5 입니다.
- return 값 형식
- 1차원 정수 배열에 5개의 원소를 담아서 return 합니다.
places
에 담겨 있는 5개 대기실의 순서대로, 거리두기 준수 여부를 차례대로 배열에 담습니다.- 각 대기실 별로 모든 응시자가 거리두기를 지키고 있으면 1을, 한 명이라도 지키지 않고 있으면 0을 담습니다.
입출력 예
places | result |
---|---|
[["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
첫 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | P | O | O | O | P |
1 | O | X | X | O | X |
2 | O | P | X | P | X |
3 | O | O | X | O | X |
4 | P | O | X | X | P |
- 모든 응시자가 거리두기를 지키고 있습니다.
두 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | P | O | O | P | X |
1 | O | X | P | X | P |
2 | P | X | X | X | O |
3 | O | X | X | X | O |
4 | O | O | O | P | P |
- (0, 0) 자리의 응시자와 (2, 0) 자리의 응시자가 거리두기를 지키고 있지 않습니다.
- (1, 2) 자리의 응시자와 (0, 3) 자리의 응시자가 거리두기를 지키고 있지 않습니다.
- (4, 3) 자리의 응시자와 (4, 4) 자리의 응시자가 거리두기를 지키고 있지 않습니다.
세 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | P | X | O | P | X |
1 | O | X | O | X | P |
2 | O | X | P | O | X |
3 | O | X | X | O | P |
4 | P | X | P | O | X |
- 모든 응시자가 거리두기를 지키고 있습니다.
네 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | O | O | O | X | X |
1 | X | O | O | O | X |
2 | O | O | O | X | X |
3 | O | X | O | O | X |
4 | O | O | O | O | O |
- 대기실에 응시자가 없으므로 거리두기를 지키고 있습니다.
다섯 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | P | X | P | X | P |
1 | X | P | X | P | X |
2 | P | X | P | X | P |
3 | X | P | X | P | X |
4 | P | X | P | X | P |
- 모든 응시자가 거리두기를 지키고 있습니다.
두 번째 대기실을 제외한 모든 대기실에서 거리두기가 지켜지고 있으므로, 배열 [1, 0, 1, 1, 1]을 return 합니다.
제한시간 안내
- 정확성 테스트 : 10초
※ 공지 - 2022년 4월 25일 테스트케이스가 추가되었습니다.
- 두 테이블 T1, T2가 행렬 (r1, c1), (r2, c2)에 각각 위치하고 있다면, T1, T2 사이의 맨해튼 거리는 |r1 - r2| + |c1 - c2| 입니다. ↩
출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
풀이
from collections import deque
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
def bfs(p) :
start = []
for i in range(5) : # 시작점이 되는 P좌표 구하기
for j in range(5) :
if p[i][j] == 'P' :
start.append((i, j))
for s in start :
q = deque()
q.append(s)
v = [[0] * 5 for _ in range(5)] # 방문 처리 리스트
d = [[0] * 5 for _ in range(5)] # 경로 길이 리스트
v[s[0]][s[1]] = 1
while q :
x, y = q.popleft()
for i in range(4) :
nx = x + dx[i]
ny = y + dy[i]
if 0<=nx<5 and 0<=ny<5 and v[nx][ny] == 0 :
if p[nx][ny] == 'O' :
q.append((nx, ny))
v[nx][ny] = 1
d[nx][ny] = d[x][y] + 1
if p[nx][ny] == "P" and d[x][y] <= 1 :
return 0
return 1
def solution(places):
answer = []
for i in places :
answer.append(bfs(i))
return answer
[프로그래머스] 거리두기 확인하기 파이썬
거리두기 확인하기 ( https://programmers.co.kr/learn/courses/30/lessons/81302
velog.io
def solution(places):
answer = []
for p in places:
# 거리두기가 지켜지지 않음을 확인하면 바로 반복을 멈추기 위한 flag
flag = False
nowArr = []
# 이번 place를 nowArr에 담아줌
for n in p:
nowArr.append(list(n))
# 이중 for문을 이용해 하나씩 확인함.
for i in range(5):
if flag:
break
for j in range(5):
if flag:
break
# 사람을 찾아내면 판단을 시작
if nowArr[i][j] == "P":
if i + 1 < 5:
# 만약 바로 아랫부분에 사람이 존재하면 break
if nowArr[i + 1][j] == "P":
flag = True
break
# 만약 아랫부분이 빈 테이블이고 그 다음에 바로 사람이 있다면 한 칸 떨어져 있더라도 맨해튼 거리는 2이므로 break
if nowArr[i + 1][j] == "O":
if i + 2 < 5:
if nowArr[i + 2][j] == "P":
flag = True
break
# 바로 오른쪽 부분에 사람이 존재하면 break
if j + 1 < 5:
if nowArr[i][j + 1] == "P":
flag = True
break
# 만약 오른쪽 부분이 빈 테이블이고 그 다음에 바로 사람이 있다면 한 칸 떨어져 있더라도 맨해튼 거리는 2이므로 break
if nowArr[i][j + 1] == "O":
if j + 2 < 5:
if nowArr[i][j + 2] == "P":
flag = True
break
# 우측 아래 부분
if i + 1 < 5 and j + 1 < 5:
# 만약 우측 아래가 사람이고, 오른쪽 또는 아랫부분 중 하나라도 빈 테이블이면 break
if nowArr[i + 1][j + 1] == "P" and (nowArr[i + 1][j] == "O" or nowArr[i][j + 1] == "O"):
flag = True
break
# 좌측 아래
if i + 1 < 5 and j - 1 >= 0:
# 만약 좌측 아래가 사람이고, 왼쪽 또는 아랫부분 중 하나라도 빈 테이블이면 break
if nowArr[i + 1][j - 1] == "P" and (nowArr[i + 1][j] == "O" or nowArr[i][j - 1] == "O"):
flag = True
break
# 위의 for문 동안 flag가 True로 변경되었다면 거리두기가 지켜지지 않은 것이므로 0을 answer에 추가
if flag:
answer.append(0)
# flag가 False로 끝났다면 거리두기가 지켜졌으므로 1을 추가
else:
answer.append(1)
# 끝!
return answer
다른 분의 풀이가 설명이 상세하고 어떤 점을 고려하였는지 설명되어있어서 좋았다.
2021 카카오 인턴십 for Tech developers 코딩 테스트 해설
2021년 카카오의 여름 인턴십의 첫 번째 관문인 코딩 테스트가 지난 2021년 5월 8일에 4시간에 걸쳐 진행되었습니다. 이번 인턴 코딩 테스트에서는 5문제가 출제되었습니다. 이전과 동일하게 쉬운
tech.kakao.com
주어진 5x5 크기의 대기실을 다음과 같은 그래프로 볼 수 있습니다.
- 하나의 칸을 정점으로 봅니다.
- 모든 칸에는 상하좌우 인접한 칸으로의 간선이 있습니다.
- 단, 파티션이 있는 칸에서 나오거나 파티션이 있는 칸으로 들어가는 간선은 없습니다.
그러면 이 문제는 사람이 있는 정점에서 거리 2 이내에 다른 사람이 있는 정점이 있는지를 검사하는 그래프 탐색 문제로 볼 수 있습니다.
따라서 사람이 있는 정점들에서 시작하는 깊이 우선 탐색(DFS) 또는 너비 우선 탐색(BFS) 알고리즘을 사용하면 해결이 가능합니다. 이때, 거리 2 이내만 확인하면 된다는 점에 유의하여 구현해야 합니다.
이 방법 이외에도, 거리 2 이내까지만 확인하면 문제를 풀 수 있기 때문에 이중 반복문을 사용해서 직접 한 칸씩 확인하는 것도 충분히 가능한 방법입니다.