본문 바로가기

알고리즘

[백준] 점프점프 18512

반응형

출처 : https://www.acmicpc.net/problem/18512

 

18512번: 점프 점프

첫째 줄에 두 사람이 한 번에 멀리뛰기를 하는 거리 X, Y와 시작 지점의 위치 값 P1, P2가 각각 공백을 기준으로 구분되어 자연수로 주어진다. (1 ≤ X, Y, P1, P2 ≤ 100)

www.acmicpc.net

문제

두 학생 A와 B가 일직선상의 트랙에서 같은 방향으로 멀리뛰기를 하고 있다. A는 한 번에 X 미터를, B는 한 번에 Y 미터를 뛴다. 두 학생의 시작 지점과 X, Y에 대한 정보가 주어졌을 때, 두 학생이 공통적으로 지나게 되는 지점 중에서 시작 지점으로부터 가장 가까운 지점을 찾는 프로그램을 작성하시오.

예를 들어 한 번에 10미터를 뛰는 A는 30의 지점에서 멀리뛰기를 시작하고, 한 번에 12미터를 뛰는 B는 8의 지점에서 시작한다고 가정하자. A가 5번의 멀리뛰기를 하고, B가 6번의 멀리뛰기를 하면 두 사람은 80의 지점을 공통으로 지나게 되며, 이는 두 학생의 시작 지점에서 가장 가까운 지점이다.

입력

첫째 줄에 두 사람이 한 번에 멀리뛰기를 하는 거리 X, Y와 시작 지점의 위치 값 P1, P2가 각각 공백을 기준으로 구분되어 자연수로 주어진다. (1 ≤ X, Y, P1, P2 ≤ 100)

출력

첫째 줄에 두 학생이 공통적으로 지나는 지점 중에서 가장 가까운 지점을 출력한다.

단, 두 학생이 공통적으로 지나는 지점이 없다면 -1을 출력한다.

풀이방법

 - 가장 앞서 있는 위치에 있는 학생을 끝까지 가게 한 후 , 방문한 지역을 true 처리한다.

 - 뒤에서 시작한 학생이 width 만큼 뛰면서 방문한지역 중, 가장 앞서 있던 학생이 방문했던 지역을 방문하면 답 !

 - 10000번 이상 할 때까지 방문하지 못한다면 -1 출력

코드

import java.util.Scanner;

public class Main {
	static int widthA, widthB, PosA, PosB;
	static int nextPosA, nextPosB;

	static boolean[] check = new boolean[100000 + 1];

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		widthA = sc.nextInt();
		widthB = sc.nextInt();
		PosA = sc.nextInt();
		PosB = sc.nextInt();

		// 처음위치가 같다면 그곳은 답이다. 위치 출력
		if (PosA == PosB) {
			System.out.println(PosA);
			return;
		}
		// 가장 앞에 있는 녀석 끝까지 뛰게 하면서 지나간 곳 체크하기
		
		// PosA가 앞에 있을 경우
		if (PosA > PosB) {

			check[PosA] = true;
			nextPosA = PosA + widthA;
			do {
				check[nextPosA] = true;
				nextPosA += widthA; // 다음 뛸 위치 갱신
			} while (nextPosA - PosA < 10000); // 10000칸 미만만 이동

			// 가장 앞에 있던애 먼저 뛰면서 지나갔던 곳 모두 기록해 놓은 상황
			int CurB = PosB + widthB;
			while (true) {
				// A뒤에 있던 B 계속 뛰어보자
				// 이동거리가 10000초과하면 아웃
				if (CurB - PosB > 10000) {
					System.out.println(-1);
					break;

				}

				// B가 들렸던 곳이라면
				if (check[CurB]) {
					System.out.println(CurB);
					return;
				}
				CurB += widthB; // B의 위치 갱신

			}
		}

		// PosB가 앞에 있을 경우
		else {
			check[PosB] = true;
			nextPosB = PosB + widthB;
			do {
				check[nextPosB] = true;
				nextPosB += widthB; // 다음 뛸 위치 갱신
			} while (nextPosB - PosB < 10000); // 10000칸 미만만 이동

			// 가장 앞에 있던애 먼저 뛰면서 지나갔던 곳 모두 기록해 놓은 상황
			int CurA = PosA + widthA;
			while (true) {
				// B뒤에 있던 A 계속 뛰어보자
				// 이동거리가 10000초과하면 아웃
				if (CurA - PosA > 10000) {
					System.out.println(-1);
					break;

				}
				// A가 들렸던 곳이라면
				if (check[CurA]) {
					System.out.println(CurA);
					return;
				}
				// A는 계속 뛴다.
				CurA += widthA;

			}
		}

	}
}

 

반응형