거리두기 확인하기 ( https://programmers.co.kr/learn/courses/30/lessons/81302#fn1 )
코로나 시대에 시행하고있는 거리두기를 배경으로 만든 문제입니다. 사람 P와 P사이의 거리가 맨허튼 거리가 2이하인 경우 거리두기를 지키지 않았다고 판단하여 거리두기를 하지 않은 집단과, 거리두기를 지킨 집단을 구분해 내는 문제입니다.
맨허튼 거리 : 두 테이블 T1, T2가 행렬 (r1, c1), (r2, c2)에 각각 위치하고 있다면, T1, T2 사이의 맨해튼 거리는 |r1 - r2| + |c1 - c2| 입니다.
다만 이 대기실에는 파티션이 존재할 수도 있으며 파티션이 사람 사이를 가로막고 있다면 맨허튼 거리에 상관없이 거리두기를 지키고 있다고 판단하게 됩니다.
저는 크게 머리를 쓰지 않고 문제에 주어진 조건을 그대로 구현하여 문제를 풀어냈습니다. 문제에서 주어지는 대기실은 크기가 5X5로 고정되어 있고 이 대기실도 5개만 주어진다고 되어있어 그리 큰 반복까지 가지 않을 것 같았기 때문입니다.
P
사람을 찾아냅니다.P
를 찾았다면 맨허튼 거리 2안에 사람이 존재하는지, 판단하여 사람이 존재하면 반복을 멈추고 0을 answer에 추가, 사람이 존재하지 않는다면 1을 answer에 추가합니다.def solution(places):
answer = [];
#place를 하나씩 확인
for p in places:
#거리두기가 지켜지지 않음을 확인하면 바로 반복을 멈추기 위한 key
key = False;
nowArr = [];
#이번 place를 nowArr에 담아줍니다.
for n in p:
nowArr.append(list(n));
#이중 for문을 이용해 하나씩 확인합니다.
for i in range(5):
if key:
break;
for j in range(5):
if key:
break;
#사람을 찾아내면 판단을 시작합니다.
if nowArr[i][j] == "P":
if i+1<5:
#만약 바로 아랫부분에 사람이 존재하면 break
if nowArr[i+1][j] == "P":
key = True;
break;
#만약 아랫부분이 빈테이블이고 그 다음에 바로 사람이 있다면 한칸 떨어져 있더라도 맨허튼 거리는 2이므로 break
if nowArr[i+1][j] == "O":
if i+2<5:
if nowArr[i+2][j] == "P":
key = True;
break;
#바로 오른쪽 부분에 사람이 존재하면 break
if j+1<5:
if nowArr[i][j+1] == "P":
key = True;
break;
#만약 오른쪽 부분이 빈테이블이고 그 다음에 바로 사람이 있다면 한칸 떨어져 있더라도 맨허튼 거리는 2이므로 break
if nowArr[i][j+1] == "O":
if j+2<5:
if nowArr[i][j+2] == "P":
key = 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"):
key = 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"):
key = True;
break;
#위의 for문동안 key가 True로 변경되었다면 거리두가기 지켜지지 않은것 이므로 0을 answer에 추가
if key:
answer.append(0);
else:
#key가 false로 끝났다면 거리두기가 지켜졌으므로 1 추가
answer.append(1);
#끝!
return answer;