날짜 | 분류 | 번호 | 알고리즘 분류 | 링크 |
21-01-20 | BOJ | 2585 | 이분탐색&bfs | www.acmicpc.net/problem/2585 |
문제 요약
- (0, 0)에서 (10000, 10000)까지 이동할 수 있는 최저의 연료통 용량 구하기
- 단, 중간에 주유를 할 수 있는 횟수는 K번 이하여야 함
- 참고사항
- 연료의 단위는 1L이며 1L당 10km 비행 가능
- 두 지점의 거리는 평면상의 거리임
풀이
- (0, 0)에서 (10000, 10000)까지 필요한 연료량을 r(최대값)으로 두고 이분탐색 진행
- mid로 목적지까지 도착할 수 있는지 없는지를 확인
- bfs 사용
- que에서 좌표를 하나 꺼내고 주어진 연료량으로 목적지까지 갈 수 있으면 true 반환
- 목적지까지 갈 수 없는데 연료횟수가 K번이면 다음 좌표로 넘어감
- 목적지 X 연료횟수도 X일 때, 모든 좌표에 대해서 방문X이고 주어진 연료량으로 갈 수 있는 좌표를 que에 삽입
비고
- 문제 읽다가 중단에 잠들었....zzZ
더보기
package b02.BOJ_2585_경비행기;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static Point[] station;
static int N, K;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
station = new Point[N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
station[i] = new Point(x, y);
}
int l = 0, r = calcFuel(0, 0, 10000, 10000);
while (l < r) {
int mid = (l + r) / 2;
if (canGo(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
System.out.println(l);
}
private static boolean canGo(int fuel) {
boolean[] visit = new boolean[N];
Queue<Point> que = new LinkedList<>();
que.offer(new Point(0, 0, 0));
while (!que.isEmpty()) {
Point cur = que.poll();
if (fuel >= calcFuel(cur.x, cur.y, 10000, 10000))
return true;
if (cur.cnt == K)
continue;
for (int i = 0; i < N; i++) {
if (visit[i] || fuel < calcFuel(cur.x, cur.y, station[i].x, station[i].y))
continue;
visit[i] = true;
que.offer(new Point(station[i].x, station[i].y, cur.cnt + 1));
}
}
return false;
}
private static int calcFuel(int x1, int y1, int x2, int y2) {
double result = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
return result / 10 == ((int) result) / 10 ? (int) result / 10 : (int) result / 10 + 1;
}
static class Point {
int x, y, cnt;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public Point(int x, int y, int cnt) {
this.x = x;
this.y = y;
this.cnt = cnt;
}
}
}
'알고리즘왕 > BOJ' 카테고리의 다른 글
[BOJ/20057/JAVA] 마법사 상어와 토네이도 (0) | 2021.04.06 |
---|---|
[JAVA/백준/20366] 같이 눈사람 만들래? (0) | 2021.01.20 |
[JAVA/백준/17940] 지하철 (0) | 2021.01.18 |
[JAVA/백준/20437] 문자열 게임 2 (0) | 2021.01.17 |
[JAVA/백준/8983] 사냥꾼 (0) | 2021.01.12 |