[백준] 10250번 : ACM 호텔- Java(자바)

이정우·2021년 9월 15일
0

백준

목록 보기
19/32

이번 문제는 손님의 방을 배정해주는 문제였습니다. 조건으로는 모든 방의 거리는 1칸에 1이고 손님은 가까운 방을 선호합니다. 또한 엘리베이터를 통해 다른 층수로 갈 수 있지만 엘리베이터는 거리에 포함되지 않습니다. 그리고 같은 거리라면 낮은 층을 선호합니다. 입력 값으로는 H(층) W(각 층의 방 수), N(N번째 도착한 손님)을 입력받았습니다.

Step 0. 해답 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class AMC_Hotel_10250 {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

	public static void check_in(int H, int W, int N) throws IOException {
		String Y; // 층 수
		String X; // 엘리베이터로부터 몇 번째 칸인가?
		if (N % H == 0) {
			Y = Integer.toString(H);
			X = String.format("%02d", (N / H));
		} else {
			Y = Integer.toString(N % H);
			X = String.format("%02d", (N / H) + 1);
		}
		System.out.println(Integer.parseInt(Y + X));

	}

	public static void main(String[] args) throws IOException {
		int T = Integer.parseInt(br.readLine()); // 테스트 개수
		int[] hotel = new int[T * 3];
		int count = 0;
		for (int i = 0; i < T; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			int st_count = st.countTokens();
			for (int j = 0; j < st_count; j++) {
				hotel[count] = Integer.parseInt(st.nextToken());
				count++;
			}
		}
		count = 0;
		for (int i = 0; i < T; i++) {
			check_in(hotel[count], hotel[count + 1], hotel[count + 2]);
			count += 3;
		}

	}

}

해답 코드 버전 2

package Basic_Math;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;


public class AMC_Hotel_10250_2 {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	public static void check_in() throws IOException{
		
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		
		int H = Integer.parseInt(st.nextToken()); // 층 수
		int W = Integer.parseInt(st.nextToken()); // 각 층의 방 수
		int N = Integer.parseInt(st.nextToken()); // 몇 번째 손님인가
		String Y; //층 수
		String X; //엘리베이터로부터 몇 번째 칸인가?
		if(N % H == 0) {
			Y = Integer.toString(H);
			X = String.format("%02d",(N / H));
		}
		else {
			Y = Integer.toString(N % H); 
			X = String.format("%02d",(N / H) + 1);
		}
		System.out.println(Y + X); 
		
	}
	public static void main(String[] args) throws IOException{
		int T = Integer.parseInt(br.readLine()); //테스트 개수
		int count = 0;
		for (int i = 0; i < T; i++) {
		check_in();
		count += 3;
		}
		
		
		
	}

}

해답 코드 1과 2의 차이점은 1에서는 반복 횟수를 입력받은 후 해당 횟수 만큼 H, W, N값들을 한 번에 저장해서 배열에 담은 후 배열에서 값을 꺼내 출력해주었습니다. 이렇게 한 이유는 문제에서는 값들을 한 번에 입력받고 출력 값이 한 번에 나오게 해주고 있었기에 똑같이 해주기 위해서였는데 2번의 방법처럼 입력 > 출력 > 입력 > 출력 순서로 해도 문제가 없는걸 알아서 두 번째 방법도 적었습니다. 또한 두 번째는 마지막에 값들을 그냥 String형태로 알려주고 있습니다. 첫 번째에서는 int형으로 줘야하는 줄 알았는데 String 형으로 줘도 정답으로 인정되는것을 알았습니다. 설명에서는 첫 번째 코드로 설명드리도록 하겠습니다.

Step 1. 문제 접근

문제 설명에도 있듯이 각 방의 번호는 YYXX형태로 만들어 집니다. Y는 층, X는 각 층의 엘리베이터에서의 거리입니다. 그렇기에 저희는 X와 Y값을 찾으면 정답을 찾을 수 있습니다. 이를 위해 N번째 손님 / H(높이)를 하여 해당 손님이 엘리 베이터에서 몇 층 떨어져 있는지를 구하고 N % H, 나머지 값을 통해서 몇 층인지도 구하였습니다.

Step 2. 문제 풀이

이번에도 BufferedReader 클래스를 사용하였습니다.

  1. check_in 메서드를 만들어서 계산하기 편하게 관리하였습니다.
public static void check_in(int H, int W, int N) throws IOException {

throws IOException부분은 해당 메서드에서는 BufferedReader 클래스를 사용하지 않았기에 안 써도 괜찮지만 혹여 다른 클래스에서 사용한다면 저렇게 예외 처리를 해줘야 한다는 것을 확인하기 위해 따로 지우는지 않았습니다. 해답 코드 2에서는 check_in 메서드에서 BufferedReader 클래스를 사용하기에 예외 처리를 해주어야 합니다.

  1. 저희가 구할 X, Y값을 찾기 위해 우선 N % H가 0인지를 확인합니다. 나머지가 0이라는 소리는 딱 나누어 떨어진다는 말이고 이 경우는 해당 칸의 가장 꼭대기 층이라는 소리입니다. 하지만 숫자로는 0으로 표시되기에 따로 관리해주었습니다.
		String Y; // 층 수
		String X; // 엘리베이터로부터 몇 번째 칸인가?
		if (N % H == 0) {
			Y = Integer.toString(H);
			X = String.format("%02d", (N / H));
		} else {
			Y = Integer.toString(N % H);
			X = String.format("%02d", (N / H) + 1);
		}
		System.out.println(Integer.parseInt(Y + X));

그 후 N/H와 N%H등을 사용하여 X,Y값을 구하였습니다. (N / H) + 1에서 +1을 해준거는 N/H 값이 0이면 엘리베이터 바로 다음 칸, 즉 YY1호 라는 말이기에 몫에 +1을 해주었습니다. 또 String.format메서드를 사용하여 0x 모양으로 문자를 뽑아냈습니다. 또한 변수를 받을 때는 BufferedReader 클래스는 String형으로 받기에 형 변환을 계속 해주어 제가 원하는 형태로 바꾸어 주었습니다. 참고로 마지막 System.out.println(Integer.parseInt(Y + X)); 에서는 따로 int형으로 바꾸지 않고 문자형으로 출력을 해줘도 백준에서 정답으로 처리하는 것을 알 수 있었습니다.

  1. 메서드가 완성 되었으니 이제 테스트 개수인 T를 입력받아 해당 횟수만큼 정답을 구해주는 식을 짜줬습니다.
public static void main(String[] args) throws IOException {
		int T = Integer.parseInt(br.readLine()); // 테스트 개수
		int[] hotel = new int[T * 3];
		int count = 0;
		for (int i = 0; i < T; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			int st_count = st.countTokens();
			for (int j = 0; j < st_count; j++) {
				hotel[count] = Integer.parseInt(st.nextToken());
				count++;
			}
		}
		count = 0;
		for (int i = 0; i < T; i++) {
			check_in(hotel[count], hotel[count + 1], hotel[count + 2]);
			count += 3;
		}

Main문에서 T를 받아 사용하였고 hotel 배열에 입력 값들을 한 번에 받아 저장해준 후 사용하였습니다. 또한 count 값을 통해 배열에 값을 3개씩 저장하도록 하였습니다. 하지만 굳이 이렇게 모든 입력을 한 번에 처리 > 한 번에 계산 후 한 번에 출력 순서가 아니라 해답 코드 2번 처럼 반복 횟수 T만큼 입력 > 계산 후 처리 > 입력 > 계산 후 처리 ...를 반복을 반복해줘도 백준에서 정답 처리를 하는 것을 알 수 있었습니다. 마지막의 check_in메서드를 불러오면서 출력 값을 프린트 했습니다.

Step 3. 느낀 점

BufferedReader 클래스나 StringTokenizer 클래스 사용에 좀 더 익숙해졌고 관련 메서드 들도 배울 수 있었습니다. 또한 예전보다 for 문 사용에 더욱 익숙해진걸 느낄 수 있었던 좋은 시간이었습니다. 그리고 백준의 정답 처리 시스템도 얼떨결에 이해하게 된 시간이었습니다!

출처 : 백준 10250번 https://www.acmicpc.net/problem/10250

profile
프로그래밍 공부 중!

0개의 댓글