정리

백준 14488번: 준오는 급식충이야!! 본문

Programming/백준 BOJ

백준 14488번: 준오는 급식충이야!!

H.J.Park 2020. 9. 30. 09:55

백준 14488번: 준오는 급식충이야!!

 

14488번: 준오는 급식충이야!!

심술쟁이 해커 임준오(동탄 주민)는 오늘도 점심시간을 기다리고 있다. 준오와 친구들은 매일 복도 어딘가의 한 지점에 모여서 함께 밥을 먹으러 간다. 선린의 복도는 직선형으로 되어있고, 준오와 친구들은 이 복도 어딘가에 위치한 교실에서 종이 치기만을 기다리고 있다.‘띵~ 디딩~ 띵디딩디딩~’.

www.acmicpc.net

 

 

  • 각 좌표에서 이동할 수 있는 범위를 구한 뒤, 모든 데이터의 교집합이 있으면 1을 출력하고 교집합이 없으면 0을 출력한다.

- 다음 예제를

3 2.5
1 7 5
2 1 1

을 살펴보자.

  • 1에서는 2.5초 동안 [-4, 6] 사이를 이동할 수 있다. 마찬가지로 7과 5에서는 각각 [4.5, 9.5], [2.5, 7.5]사이를 이동할 수 있다. 교집합이 [4.5, 6]으로 존재하므로 이 경우에는 만날 수 있다.
  • 따라서 좌표x에 (v*t)를 각각 더하고 빼서 x의 이동 가능 범위를 구한뒤 교집합을 찾으면 된다. 양의 방향으로 움직을 때의 최솟값이 음의 방향으로 움직일 때의 최댓값보다 크거나 같으면 1을 출력하고 그 외의 경우에는 0을 출력하면 된다.

- 그래서 위를 바탕으로 자바 코드를 짜보면 아래와 같다.

import java.util.*;
import java.io.*;

public class Main{
    static int n;
    static double t;
    static double[] x;
    static double[] v;
    static double MIN_RANGE = 1000000001;
    static double MAX_RANGE = 0;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        n = Integer.parseInt(st.nextToken());
        t = Double.parseDouble(st.nextToken());

        x = new double[n];
        v = new double[n];

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++)
            x[i] = Double.parseDouble(st.nextToken());
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++)
            v[i] = Double.parseDouble(st.nextToken());

        for (int i = 0; i < n; i++) {
            MIN_RANGE = Math.min(MIN_RANGE, x[i] + v[i] * t);
            MAX_RANGE = Math.max(MAX_RANGE, x[i] - v[i] * t);
        }

        if (MIN_RANGE >= MAX_RANGE)
            System.out.println(1);
        else
            System.out.println(0);
    }
}

※ 언뜻보면 통과할 것 같지만 위 코드는 통과하지 못한다. 왜냐하면 t가 소숫점 아래 4자리의 실수이기 때문이다. double형 실수의 부동소수점 방식 때문에 정확한 비교가 어려워서 오차가 발생하기 때문이다. 따라서 Math.min()과 Math.max()를 사용할 때 Math.round()를 통해서 소숫점 아래 4자리에서 반올림을 한 뒤 비교를 하면 통과할 수 있다. 백준의 질문 게시판의 이 글을 참고하면 도움이 많이 될 것 같다.

 

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

백준 1789번: 수들의 합  (0) 2020.12.25
백준 2493번: 탑  (0) 2020.10.12
백준 2109번: 순회강연  (0) 2020.09.30
백준 1461번: 도서관  (0) 2020.09.28
백준 2473번: 세 용액  (0) 2020.09.21
Comments