알고리즘 공부
[2021 카카오 하계 인턴십 코딩테스트] 2번 거리두기 확인하기 | Python3
유나쒸
2021. 7. 11. 21:18
1. 문제 설명
- 5x5 대기실 별로 거리두기를 지키고 있으면 1, 그렇지 않으면 0 을 배열에 담아 리턴
-
- 거리두기를 위하여 응시자들 끼리는 맨해튼 거리( | x1-x2 | + | y1-y2 | )가 2 이하로 앉지 말아 주세요.
- 단 응시자가 앉아있는 자리 사이가 파티션으로 막혀 있을 경우에는 허용합니다.
- 예를 들어,
* 파이썬 이중 리스트 인덱싱 편의 상 (y,x) 좌표라고 하겠습니다
- P(0,0)과 P(2,0) 의 거리는 2이며 사이 (1,0)에 파티션(X)가 없으므로 거리두기를 지키고 있지 않다.
- P(0,3)과 P(1,2) 의 거리는 2이며 대각선 (0,2)에 파이션(X)가 없으므로 거리두기를 지키고 있지 않다.
- P(0,3)과 P(1,4) 의 거리는 2이며 두 대각선 (0,4), (1,3)에 파이션(X)이 있으므로 거리두기를 지키고 있다.
- P(4,3)과 P(4,4) 의 거리는 1이므로 거리두기를 지키고 있지 않다.
- 그러므로 0을 리턴한다.
2. 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
def solution(places):
answer = []
for place in places: answer.append(DoesHavingDistance(place))
return answer
# 대기실의 모든 응시자 위치 반환
def IndexOfP(waitingmap):
Index_of_P=[]
for IndexOfRow, Row in enumerate(waitingmap):
index=-1
while True:
index=Row.find('P', index+1)
if index==-1: break
else: Index_of_P.append([IndexOfRow, index])
return Index_of_P
# 대기실이 거리두기 지키는지 파악
def DoesHavingDistance(waitingmap):
Index_Of_P=IndexOfP(waitingmap) # 모든 응시자 위치 반환
# 이중 for문으로 두 응시자의 거리 비교
for Idx, P in enumerate(Index_Of_P):
for OtherP in Index_Of_P[Idx+1:]:
dx=P[0]-OtherP[0]; dy=P[1]-OtherP[1]
distance=abs(dx)+abs(dy)
if distance>2: continue # 거리 > 2 인 경우
elif distance<=1: return 0 # 거리 <=1 이므로 거리두기 지키지 않고 있음
else: # 거리=2인 경우 확인
if dx!=0 and dy!=0: # x좌표의 차와 y좌표의 차가 모두 0이 아니면 두 응시자는 대각선에 위치
# 두 응시자 사이 두 대각선 'O' 인지 'X' 인지 확인. 둘다 'X'이여야만 거리두기 지킴
if waitingmap[OtherP[0]+dx][OtherP[1]]=='O' or waitingmap[OtherP[0]][OtherP[1]+dy]=='O': return 0
# 두 응시자의 X좌표는 같고 Y좌표만 다른 경우 두 Y좌표 사이 좌표 값 'O'/'X' 여부 확인
elif dx==0 and waitingmap[P[0]][(P[1]+OtherP[1])//2]=='O': return 0
# 두 응시자의 Y좌표는 같고 X좌표만 다른 경우 두 X좌표 사이 좌표 값 'O'/'X' 여부 확인
elif waitingmap[(P[0]+OtherP[0])//2][P[1]]=='O': return 0
return 1
|
cs |
- 응시자(P) 간 거리와 사이 파티션 존재 여부만 파악하면 되므로 먼저 대기실의 모든 P의 위치 계산 - IndexOfP 함수
- 이중 반복문을 이용해 응시자(P) 간 거리 비교 - DoesHavingDistance 함수
- 거리 > 2인 경우 -> 거리두기 지킴
- 거리 = 1인 경우 -> 거리두기 지키지 않음, 한 명이라도 지키지 않으면 대기실 거리두기 지키지 않는 것이므로 바로 0 리턴하여 함수 종료
- 거리 = 2인 경우 응시자 사이 파티션(X) 존재 비교해야함
- 두 응시자가 대각선에 있는 경우(dx!=0 and dy!=0), 대각선 사이에 위치한 좌표 두개가 모두 파티션(X)이여야 -> 거리두기 지킴
- 두 응시자의 y좌표만 다른 경우(dx-=0) , 두 y좌표 사이 좌표가 파티션(X)이여야 -> 거리두기 지킴
- 두 응시자의 x좌표만 다른 경우, 두 x좌표 사이 좌표가 파티션(X)이여야 -> 거리두기 지킴