본문 바로가기

PS/백준

[BOJ] 백준 1004 어린왕자 (Swift)

반응형

문제

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

 

1004번: 어린 왕자

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 첫째 줄에 출발점 (x1, y1)과 도착점 (x2, y2)이 주어진다. 두 번째 줄에는 행성계의 개수 n이 주

www.acmicpc.net

풀이

출발점에서 도착점으로 이동하면서 행성에 진입하거나, 이탈할 때의 횟수를 구하는 문제입니다.

진입하거나 이탈할 때를 어떻게 알 수 있을까요?

먼저 출발점과 도착점을 그려봅시다.

IMG_2A807C5C4899-1

아무런 행성이 없는 경우, 행성에 진입/이탈 할 필요가 없겠죠??

다음 두 경우에도 행성에 진입/이탈 할 필요가 없을 것입니다.

IMG_AFF0642FD608-1IMG_891F9331EF13-1

다음과 같은 경우에 진입/이탈을 해야합니다.

IMG_748465848EFA-1IMG_F98A451D67C4-1

행성이 출발점을 두르고있거나, 도착점을 두르는 경우 진입/이탈을 해야합니다.

이것을 어떻게 표현할 수 있을까요?

출발점 혹은 도착점으로부터 행성의 중심점까지의 거리행성의 반지름보다 작다면 행성에 둘러 쌓여있다고 말할 수 있습니다.

하지만 출발점과 도착점이 둘 다 행성에 둘러쌓인경우진입/이탈할 필요가 없겠죠??
따라서 출발점만 둘러쌓여있거나, 도착점만 둘러 쌓여있는 경우진입/이탈을 시도하게 됩니다.

소스코드로 작성할 때, 두 점사이의 거리는 원래 루트를 씌워주어야 하지만, 루트를 안씌워주고 반지름까지 제곱해서 구하는 방식으로 구현하였습니다.

소스코드

func solution() {
let input = readLine()!.split(separator: " ").map { Int($0)! }
let x1 = input[0], y1 = input[1], x2 = input[2], y2 = input[3]
let n = Int(readLine()!)!
var count = 0
for _ in 0..<n {
let input = readLine()!.split(separator: " ").map { Int($0)! }
let x = input[0], y = input[1], r = input[2]
// 출발점 - 행성의 중심까지의 거리
let distance1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y)
// 도착점 - 행성의 중심까지의 거리
let distance2 = (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)
// 거리에 route를 씌워주지 않아서 반지름을 제곱해줌
let powR = r * r
// 두 거리가 반지름보다 작다면 (전부 행성에 포함되므로 진입/이탈 X)
if powR > distance1 && powR > distance2 {
continue
}
// 출발점으로부터의 거리가 반지름보다 작다면 (행성에 포함되므로 도착점을 지날때, 행성을 이탈하여야 함)
if powR > distance1 {
count += 1
}
// 도착점에서 행성의 중심으로부터의 거리가 반지름보다 작다면 (행성에 포함되므로 도착점을 지날때, 행성에 진입하여야 함)
if powR > distance2 {
count += 1
}
}
print(count)
}
let t = Int(readLine()!)!
for _ in 0..<t { solution() }

후기

문제가 잘 이해되지 않을 수 있습니다.
저는 예제입력을 직접 그려보면서 이해하는데 도움을 얻었습니다.
행성에 둘러쌓여있는지는 체크하는것이 핵심인 문제였습니다.

반응형

'PS > 백준' 카테고리의 다른 글