n
, m
: 블록 가로의 길이, 세로의 길이
nums
: 상점의 개수
동근이 위치와 각 상점 간 최단 거리의 합을 구하는 문제이다.
⭐️ 블록 설명
- n ⅹ m의 블록에서 중간에 가로지를 수 있는 통로 ❌
- 블록 둘레에 상점들이 위치
- 이동 시, 둘레 따라 이동
- 상점 위치, 동근 위치는 블록 꼭짓점 ❌
- 위치의 의미
- 첫째 수 : 상점 위치 방향
- 1 : 북쪽
- 2 : 남쪽
- 3 : 서쪽
- 4 : 동쪽
- 둘째 수 : 경계로부터의 거리
- 북 & 남 : 왼쪽으로부터
- 동 & 서 : 위쪽으로부터
블록의 경계선을 따라 이동해야 하므로 시계 방향, 반시계 방향 2가지 이동 방법이 있다.
→ 2가지의 방법으로 각 상점까지의 거리를 계산하고 더 짧은 길이를 더해주면 될 것이다.
(반시계방향 계산의 용이함을 위해 전체 둘레 길이를 미리 계산)
블록의 맨 위 왼쪽 위치를 (0, 0)으로 생각하고 이 위치부터 각 상점의 위치까지의 거리를 계산한다.
→ 방향을 의미하는 첫째 수에 따라 거리 계산 방식을 다르게 해야 한다.
거리로 바꾸는 과정을 동근이 위치, 각 상점의 위치에 대해서 진행할 것이므로 이용하기 편하도록 따로 함수화해준다.
동근이 위치와 각 상점 위치를 거리로 변환한 후 그 차이를 계산하면 시계 방향으로 이동했을 경우의 거리를 얻을 수 있다..
→ 이 값을 전체 둘레 합에서 빼서 반시계 방향 이동 시 거리를 구한다.
→ 두 값 중 더 최소를 최단 거리 누적합에 계산하면 된다.
상점 위치 입력 →
거리 계산 →
최종 시간복잡도
가 되어 최악의 경우 이 되는데 이는 1초내 연산 가능하다.
각 상점 위치를 기준점으로부터의 거리로 계산해서 최단 거리 찾기
30
만 나왔다.answer
변수에 최단 거리 합을 담았는데 total_distance
라는 전체 둘레를 의미하는 변수를 출력해서 예제 입력1의 둘레인 30
이 출력된 것이었다.import sys
input = sys.stdin.readline
# 거리 계산
def calculate_distance(direction, distance):
if direction == 1:
return distance
elif direction == 2:
return 2 * n + m - distance
elif direction == 3:
return 2 * (n + m) - distance
elif direction == 4:
return n + distance
# 블록 가로, 세로 길이 입력
n, m = map(int, input().split())
# 상점 개수 입력
nums = int(input())
# 상점 위치 입력
locations = [list(map(int, input().split())) for _ in range(nums)]
# 동근 위치 입력
start = list(map(int, input().split()))
# 전체 둘레 계산
total_distance = 2 * (n + m)
# 동근 위치 거리 변환
start_distance = calculate_distance(start[0], start[1])
# 최단 거리 합 저장할 변수 정의
answer = 0
# 각 상점에 대해 거리 계산 후 최솟값 찾기
for location in locations:
store_distance = calculate_distance(location[0], location[1])
# 시계방향 거리 계산
distance1 = abs(start_distance - store_distance)
# 반시계방향 거리 계산
distance2 = total_distance - distance1
# 최단 거리 합 선택
answer += min(distance1, distance2)
# 결과 출력
print(answer)