알고리즘 공부

[2021 카카오 하계 인턴십 코딩테스트] 2번 거리두기 확인하기 | Python3

유나쒸 2021. 7. 11. 21:18

1. 문제 설명

  • 5x5 대기실 별로 거리두기를 지키고 있으면 1, 그렇지 않으면 0 을 배열에 담아 리턴
    1. 거리두기를 위하여 응시자들 끼리는 맨해튼 거리( | x1-x2 | + | y1-y2 | )가 2 이하로 앉지 말아 주세요.
    2. 단 응시자가 앉아있는 자리 사이가 파티션으로 막혀 있을 경우에는 허용합니다.
  • 예를 들어, 

대기실 예시

   * 파이썬 이중 리스트 인덱싱 편의 상 (y,x) 좌표라고 하겠습니다

  1. P(0,0)과 P(2,0) 의 거리는 2이며 사이 (1,0)에 파티션(X)가 없으므로 거리두기를 지키고 있지 않다.
  2. P(0,3)과 P(1,2) 의 거리는 2이며 대각선 (0,2)에 파이션(X)가 없으므로 거리두기를 지키고 있지 않다.
  3. P(0,3)과 P(1,4) 의 거리는 2이며 두 대각선 (0,4), (1,3)에 파이션(X)이 있으므로 거리두기를 지키고 있다.
  4. P(4,3)과 P(4,4) 의 거리는 1이므로 거리두기를 지키고 있지 않다. 
  5. 그러므로 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<=1return 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
  1. 응시자(P) 간 거리와 사이 파티션 존재 여부만 파악하면 되므로 먼저 대기실의 모든 P의 위치 계산 - IndexOfP 함수
  2. 이중 반복문을 이용해 응시자(P) 간 거리 비교 - DoesHavingDistance 함수
    1. 거리 > 2인 경우 -> 거리두기 지킴
    2. 거리 = 1인 경우 -> 거리두기 지키지 않음, 한 명이라도 지키지 않으면 대기실 거리두기 지키지 않는 것이므로 바로 0 리턴하여 함수 종료
    3. 거리 = 2인 경우 응시자 사이 파티션(X) 존재 비교해야함
      1. 두 응시자가 대각선에 있는 경우(dx!=0 and dy!=0), 대각선 사이에 위치한 좌표 두개가 모두 파티션(X)이여야 -> 거리두기 지킴
      2. 두 응시자의 y좌표만 다른 경우(dx-=0) , 두 y좌표 사이 좌표가 파티션(X)이여야 -> 거리두기 지킴
      3. 두 응시자의 x좌표만 다른 경우, 두 x좌표 사이 좌표가 파티션(X)이여야 -> 거리두기 지킴