Notice
Recent Posts
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 1011
- dp
- Repository
- 8장
- 6장
- 수학
- 1024
- 클린코드
- mirror
- 기하학
- 프로그래머스
- 3장
- Wiki
- 4장
- N으로 표현
- 백준
- recursion
- inductive step
- 자기호출
- 재귀
- 원의 방정식
- 2장
- 문제풀이
- Clean code
- 규칙
- 0장
- basis step
- programmers
- 7장
- BOJ
Archives
- Today
- Total
LeeA0의 공부 일기
[백준] 1004 어린왕자 본문
안녕하세요.
BOJ 1004 어린왕자를 풀어봤습니다.
문제 분석

은하수 지도, 출발점, 도착점이 주어졌을 때 어린 왕자에게 필요한 최소의 행성계 진입/이탈 횟수를 구하는 프로그램을 작성해 보자.(행성계의 경계가 맞닿거나 서로 교차하는 경우는 없다고 가정한다.또한, 출발점이나 도착점이 행성계 경계에 걸쳐진 경우 역시 입력으로 주어지지 않는다.)
=> 최대한 원의 경계를 관통하지 않으면서 출발점에서 도착점으로 이동한다.
풀이 방법
행성이 하나만 있다고 가정했을 때 출발점과 도착점의 경우의 수는 다음과 같다.

1) 행성을 한 번도 통과하지 않고 갈 수 있다.
2) 도착점에 가기 위해선 반드시 행성을 한 번 진입해야 한다.
3) 1번과 마찬가지로 행성을 한 번도 통과하지 않고 갈 수 있다.
4) 도착점에 가기 위해선 반드시 행성을 한 번 이탈해야 한다.
이를 단순하게 봤을 때, 원안에 하나의 점(출발점 혹은 도착점)이 들어가있다면 반드시 진입(혹은 이탈)을 해야함을 의미한다.
그렇다면, 출발점 혹은 도착점이 원 안에 있다는 것은 어떻게 알 수 있을까?

바로, 원의 방정식을 이용하는 것이다.

x와 y값에 해당 점을 대입했을 때 식을 만족하면 해당 점이 원안쪽에 있는 것이다.
다음 테스트 케이스를 통해 예시를 들어보겠다.
-5 1 12 1
7
1 1 8
-3 -1 1
2 2 2
5 5 1
-4 5 1
12 1 1
12 1 2

- 원1 - 중심: (1,1) / 반지름: 8
- 시작점 < 64 (이탈)
- 끝점 > 64
- 원2 - 중심: (-3,-1) / 반지름: 1
- 시작점 > 1
- 끝점 > 1
- 원3 - 중심: (2,2) / 반지름: 2
- 시작점 > 4
- 끝점 > 4
- 원4 - 중심: (5,5) / 반지름: 1
- 시작점 > 1
- 끝점 > 1
- 원5 - 중심: (-4,5) / 반지름: 1
- 시작점 > 1
- 끝점 > 1
- 원6 - 중심: (12,1) / 반지름: 1
- 시작점 > 1
- 끝점 < 1 (진입)
- 원7 - 중심: (12,1) / 반지름: 2
- 시작점 > 4
- 끝점 < 4 (진입)
=> 총 진입/이탈 횟수는 3번이 된다.
코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ_1004_어린왕자 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();
for (int t = 0; t < T; t++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int sx = Integer.parseInt(st.nextToken());
int sy = Integer.parseInt(st.nextToken());
int ex = Integer.parseInt(st.nextToken());
int ey = Integer.parseInt(st.nextToken());
int n = Integer.parseInt(br.readLine());
int count = 0;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
int r = Integer.parseInt(st.nextToken());
if (include(sx, sy, x, y, r)^include(ex, ey, x, y, r)) {
count++;
}
}
sb.append(count).append("\n");
}
System.out.print(sb);
}
static boolean include(int gx, int gy, int x, int y, int r) {
return Math.pow(gx - x, 2) + Math.pow(gy - y, 2) < Math.pow(r, 2);
}
}'Algorithm > 문제풀이' 카테고리의 다른 글
| [프로그래머스] N으로 표현 (0) | 2021.08.31 |
|---|---|
| [백준] 1024 수열의 합 (0) | 2021.03.02 |
| [백준] 1011 Fly me to the Alpha Centauri (0) | 2021.03.01 |
Comments