문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/81302
풀이
이 문제는 BFS로도 풀 수 있으나 배열의 크기가 5 X 5로 상당히 작으며 또한 맨해튼 거리가 2 이내인 경우가 아래의 6가지 경우 밖에 없기에 이 경우만 조건문으로 체크해 주면 더 간단하게 풀이가 될 것이라고 판단하여 BFS를 사용하지 않았다.
- 아래가 사람인 경우
- 두 칸 아래가 사람이며 중간에 파티션이 없는 경우
- 오른쪽 대각선 아래가 사람이며 중간에 파티션이 없는 경우
- 왼쪽 대각선 애라개 사람이며 중간에 파티션이 없는 경우
- 오른쪽이 사람인 경우
- 두 칸 오른쪽이 사람이며 중간에 파티션이 없는 경우
위의 경우에 만족하는 경우가 한 사람이라도 있으면 0을 반환하게 하고, 모두 통과하게 되었으면 1을 반환해 주면 된다.
좌측 상단부터 체크하기에 왼쪽에 위치한 사람이나 위에 위치한 사람은 체크하지 않는다.
def solution(places):
return [check(place) for place in places] # 각 교실 별로 거리두기 여부 체크
def check(place):
for ridx, row in enumerate(place):
for cidx, cell in enumerate(row):
if cell != "P": # 사람이 아닌 경우에는 체크할 필요 없음
continue
if ridx != 4: # 제일 아래 행이 아닐 때 체크
down = place[ridx + 1][cidx]
if down == "P": return 0 # 아래가 사람인 경우
if ridx < 3: # 두 칸 아래도 배열을 벗어나지 않을 때 체크
double_down = place[ridx + 2][cidx]
if down != "X" and double_down == "P": return 0 # 두 칸 아래가 사람이고 중간에 파티션이 없는 경우
if cidx != 4: # 제일 오른쪽 열이 아닐 때 체크
right = place[ridx][cidx + 1]
right_down = place[ridx + 1][cidx + 1]
if right_down == "P" and (down != "X" or right != "X"): return 0 # 오른쪽 대각선 아래가 사람이고 중간에 파티션이 없는 경우
if cidx != 0: # 첫번째 열이 아닐 때 체크
left = place[ridx][cidx - 1]
left_down = place[ridx + 1][cidx - 1]
if left_down == "P" and (down != "X" or left != "X"): return 0 # 왼쪽 대각선 아래가 사람이고 중간에 파티션이 없는 경우
if cidx != 4: # 제일 오른쪽 열이 아닐 때 체크
right = place[ridx][cidx + 1]
if right == "P": return 0 # 오른쪽이 사람인 경우
if cidx < 3: # 오른쪽 두 칸 옆도 배열을 벗어나지 않을 때 체크
right_twice = place[ridx][cidx + 2]
if right_twice == "P" and right != "X": return 0 # 두 칸 오른쪽이 사람이고 중간에 파티션이 없는 경우
return 1 # 위 모든 경우가 아니라면 모두 거리두기를 지킨 것이므로 1 반환
'알고리즘 > 알고리즘 문제 풀이' 카테고리의 다른 글
[프로그래머스 Lv.2] 튜플 (Python) (0) | 2024.05.13 |
---|---|
[프로그래머스 Lv.2] 행렬의 곱셈 (Python) (0) | 2024.05.10 |
[프로그래머스 Lv.2] 삼각 달팽이 (Python) (0) | 2024.05.07 |
[프로그래머스 Lv.2] 행렬 테두리 회전하기 (Python) (0) | 2024.05.06 |
[프로그래머스 Lv.2] 교점에 별 만들기 (Python) (2) | 2024.05.04 |