문제
ACM 호텔 매니저 지우는 손님이 도착하는 대로 빈 방을 배정하고 있다. 고객 설문조사에 따르면 손님들은 호텔 정문으로부터 걸어서 가장 짧은 거리에 있는 방을 선호한다고 한다. 여러분은 지우를 도와줄 프로그램을 작성하고자 한다. 즉 설문조사 결과대로 호텔 정문으로부터 걷는 거리가 가장 짧도록 방을 배정하는 프로그램을 작성하고자 한다.
문제를 단순화하기 위해서 호텔은 직사각형 모양이라고 가정하자. 각 층에 W 개의 방이 있는 H 층 건물이라고 가정하자 (1 ≤ H, W ≤ 99). 그리고 엘리베이터는 가장 왼쪽에 있다고 가정하자(그림 1 참고). 이런 형태의 호텔을 H × W 형태 호텔이라고 부른다. 호텔 정문은 일층 엘리베이터 바로 앞에 있는데, 정문에서 엘리베이터까지의 거리는 무시한다. 또 모든 인접한 두 방 사이의 거리는 같은 거리(거리 1)라고 가정하고 호텔의 정면 쪽에만 방이 있다고 가정한다.
방 번호는 YXX 나 YYXX 형태인데 여기서 Y 나 YY는 층 수를 나타내고 XX는 엘리베이터에서부터 세었을 때의 번호를 나타낸다. 즉, 그림 1에서 빗금으로 표시한 방은 305 호가된다.
손님은 엘리베이터를 타고 이동하는 거리는 신경 쓰지 않는다. 다만 걷는 거리가 같을 때에는 아래층의 방을 더 선호한다. 예를 들면 102 호 방보다는 301 호 방을 더 선호하는데, 102 호는 거리 2 만큼 걸어야 하지만 301 호는 거리 1 만큼만 걸으면 되기 때문이다. 같은 이유로 102 호보다 2101 호를 더 선호한다.
E L E V A T O R |
601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 |
501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | |
401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | |
301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | |
201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | |
101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 |
여러분이 작성할 프로그램은 초기에 모든 방이 비어있다고 가정하에 이 정책에 따라 N 번째로 도착한 손님에게 배정될 방 번호를 계산하는 프로그램이다. 첫 번째 손님은 101 호, 두 번째 손님은 201 호 등과 같이 배정한다. 그림 1의 경우를 예로 들면, H = 6이므로 10 번째 손님은 402 호에 배정해야 한다.
입력
프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수를 포함하고 있으며 각각 호텔의 층 수, 각 층의 방 수, 몇 번째 손님인지를 나타낸다(1 ≤ H, W ≤ 99, 1 ≤ N ≤ H × W).
출력
프로그램은 표준 출력에 출력한다. 각 테스트 데이터마다 정확히 한 행을 출력하는데, 내용은 N 번째 손님에게 배정되어야 하는 방 번호를 출력한다.
문제 접근 방법
이번 문제는 매 케이스마다 호텔의 층수, 호수가 달라지는 문제이다. 따라서 테스트 케이스마다 계산을 다시 해주어야 하는데, 만약 문제에서 든 예시를 예시로 들면 손님의 순서대로 101, 201, 301, 401, 501, 601, 102, 202,... 순으로 배정을 해주게 된다. 이때 객실의 패턴을 이해해야 하는데 객실의 호수가 3자리 수면 백의 자리는 객실의 층수, 뒷 두 자리는 호수를 의미한다. 객실의 호수가 4자리 수면 앞 두 자리는 객실의 층수, 뒷 두 자리는 호수를 의미한다. 따라서 (손님의 순서-1)에서 ACM호텔의 층수를 나눈 몫에 1을 더하면 그 손님의 객실 호수가 나오고, (손님의 순서-1)에서 ACM호텔의 층수를 나눈 나머지에 1을 더한 값이 해당 손님의 객실의 층을 나타낸다. 따라서 이 두 숫자를 조합하면 되는데 이때, 층수는 그냥 숫자 그대로 나타내면 되지만, 호수의 경우 일의 자리 수여도 앞에 0을 붙여 두 자릿수로 나타내야 한다. 따라서 출력할 때 포맷 형식을 지정하여 출력해주면 되는 문제이다.
* 이때 테스트 케이스가 많아질수록 Scanner함수를 사용할 때와 BufferedReader함수를 사용할 때 효율이 차이가 나므로 두 가지 코드로 비교를 해보도록 하겠다.
JAVA 코드 풀이
- Scanner VER.
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner input = new Scanner(System.in);
int tC = input.nextInt();
int h, w, n;
for(int i=0; i<tC; i++){
h = input.nextInt();
w = input.nextInt();
n = input.nextInt();
System.out.printf("%d%02d\n", (n-1)%h+1, (n-1)/h+1);
}
}
}
- BufferedReader VER.
import java.util.*;
import java.io.*;
public class Main{
public static void main(String args[]) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int tC = Integer.parseInt(br.readLine());
int h, w, n;
for(int i=0; i<tC; i++){
StringTokenizer st = new StringTokenizer(br.readLine());
h = Integer.parseInt(st.nextToken());
w = Integer.parseInt(st.nextToken());
n = Integer.parseInt(st.nextToken());
System.out.printf("%d%02d\n", (n-1)%h+1, (n-1)/h+1);
}
}
}
후기
객실이 배정되는 알고리즘과 객실의 호수가 정해지는 원리를 알고 있으면 쉽게 풀 수 있는 문제이다.
입력이 많아질수록 두 코드의 효율 차이는 커질 것으로 예상된다.
문제 원본
'문제 풀이 > [JAVA_자바] 백준' 카테고리의 다른 글
[JAVA / 자바] 백준 1011번 - Fly me to the Alpha Centauri (0) | 2021.12.23 |
---|---|
[JAVA / 자바] 백준 2839번 - 설탕 배달 (0) | 2021.12.21 |
[JAVA / 자바] 백준 2869번 - 달팽이는 올라가고 싶다 (0) | 2021.12.17 |
[JAVA / 자바] 백준 1712번 - 손익분기점 (0) | 2021.12.16 |
[JAVA / 자바] 백준 2941번 - 크로아티아 알파벳 (0) | 2021.12.15 |