ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [BOJ 20041, Python 3] Escaping
    알고리즘/BOJ 2021. 9. 9. 11:40
    반응형

    https://www.acmicpc.net/problem/20041

     

    20041번: Escaping

    첫 번째 줄에는 경찰의 수 N이 주어진다. 단, 1 ≤ N ≤ 500,000이다. 그 다음 N 개의 줄에는 각 경찰의 초기 위치의 좌표 (xi, yi)가 공백을 사이에 두고 주어진다. 다음 줄에는 도둑의 초기 위치의 좌

    www.acmicpc.net

     

    풀이

    문제에서 예시 그림을 제공하여 쉽게 이해할 수 있던 문제입니다.

    잘 생각해보면 도둑은 상하좌우 네 방향중 한 곳으로 쭉 도망치는 것이 제일 효율적으로 도망치는 것을 알 수 있습니다.

    왜냐하면 만약 도둑이 원래 가던 방향이 아닌 90도 직각으로 꺾어서 한 칸 이동하면 경찰도 그만큼 한 칸 더 이동하여 방어적으로 펼칠 수 있기 때문입니다.

     

    경찰의 위치는 (x, y)라고 하고, 도둑은 (Sx, Sy)라고 하면 경찰이 도둑을 막을 수 있는 방법은 (Sx, y)나 (x, Sy)로 이동하는 선택지만 남게됩니다.

    여기서도 abs(Sx - x) == abs(Sy - y)가 아니라면 한 방향으로만 막을 수 있는 것이죠(두 방향을 막는 경우는 본문 탈출 불가능 예시 사진 참조)

     

    이해를 쉽게하기 위해 도둑의 위치를 (0, 0)으로 잡아봅시다.

    만약 경찰의 위치는 (1, 9)라고 하면 경찰은 (0, 9)로 이동하여 한 칸만 이동하여 도둑이 윗방향으로 9칸을 가야 도착할 좌표에 미리 대기하여 막을 수 있습니다. 하지만 경찰이 (1, 0)으로 이동한다면 경찰은 아홉칸을 이동해야 (1, 0)에 도착하지만, 도둑은 한 칸만 이동하면 (1, 0)에 도착해서 도둑이 이미 도망갈 수 있으니 저 경찰은 한 방향으로만 막을 수 있는 것이 최선입니다.

     

    만약 경찰의 위치가 (-5, -3)이라고 하면 경찰은 (-5, 0)으로 이동하여 3칸만 이동하여 도둑이 왼쪽으로 5칸 가야 도착할 좌표를 미리 대기하여 막을 수 있습니다. (0, -3)으로 이동한다면 위와 같은 이유로 도둑을 막을 수 없습니다.

     

    이렇게 상하좌우 네 방향의 bool변수를 만들어서 위와 같은 방법으로 도둑이 도망칠 수 있는 곳이 존재하면 YES, 아니라면 NO를 출력하면 됩니다.

    도둑의 위치를 (0, 0)으로 좌표 변환을 한다면 제 1사분면, 제 2사분면, ... 이렇게 확인할 수 있어서 더 좋은 것 같습니다.

     

     

    저는 if문을 도배해서 풀었는데, 더 간단한 코드가 분명 있을겁니다.

    도둑의 위치를 (0, 0)으로 좌표변환을 할 때 계산을 이상하게 해서 몇 번 틀렸네요..

    코드

    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
    input = __import__('sys').stdin.readline
    = int(input())
    arr = [[*map(int, input().split())] for _ in range(n)]
    sx, sy = map(int, input().split())
    up, down, left, right = TrueTrueTrueTrue
    for i in range(n):
        arr[i][0-= sx
        arr[i][1-= sy
    for x, y in arr:
        if x >= 0 and y >= 0:
            if x == y: up, right = FalseFalse
            elif min(x, y) == x: up = False
            else: right = False
        if x >= 0 and y <= 0:
            if x == abs(y): right, down = FalseFalse
            elif min(x, abs(y)) == x: down = False
            else: right = False
        if x <= 0 and y >= 0:
            if abs(x) == y: left, up = FalseFalse
            elif min(abs(x), y) == abs(x): up = False
            else: left = False
        if x <= 0 and y <= 0:
            if abs(x) == abs(y): left, down = FalseFalse
            elif min(abs(x), abs(y)) == abs(x): down = False
            else: left = False
    if up or down or left or right: print('YES')
    elseprint('NO')
    cs

     

    반응형

    '알고리즘 > BOJ' 카테고리의 다른 글

    [BOJ 1019, Python 3] 책 페이지  (0) 2021.09.13
    [BOJ 20047, C++] 동전 옮기기  (0) 2021.09.10
    [BOJ 20046, Python 3] Road Reconstruction  (0) 2021.09.08
    [BOJ 20040, C++] 싸이클 게임  (0) 2021.09.08
    [BOJ 20044, Python 3] Project Teams  (0) 2021.09.08

    댓글

Designed by Tistory.