[백준] 10250번 : ACM 호텔 - JAVA [자바]
https://www.acmicpc.net/problem/10250
10250번: ACM 호텔
문제 ACM 호텔 매니저 지우는 손님이 도착하는 대로 빈 방을 배정하고 있다. 고객 설문조사에 따르면 손님들은 호텔 정문으로부터 걸어서 가장 짧은 거리에 있는 방을 선호한다고 한다. 여러분은 지우를 도와 줄 프로그램을 작성하고자 한다. 즉 설문조사 결과 대로 호텔 정문으로부터 걷는 거리가 가장 짧도록 방을 배정하는 프로그램을 작성하고자 한다. 문제를 단순화하기 위해서 호텔은 직사각형 모양이라고 가정하자. 각 층에 W 개의 방이 있는 H 층 건물이라고 가정
www.acmicpc.net
-
문제
수학 카테고리 문제 중 쉬운편에 속하는 문제다.
그리 어렵지 않으니 하나씩 알아보자.
- 2가지 입력방법을 이용하여 풀이한다.
Scanner 로 입력받아 연산하는 방법과 BufferedReader 로 입력받아 연산하는 방법, 두 가지 방법을 통해 풀이해보고자 한다.
- 알고리즘
먼저 조건을 잘 봐야한다.
방을 배정할 때 우선순위는 다음과 같다.
- 엘레베이터로부터 가까운 거리부터 배정
- 거리가 같은 경우 낮은 층수부터 배정
즉, 아래와 같은 순서로 배정된다는 것이다.
그리고 방 번호는 YYX 또는 YYXX 다.
이 때, Y 는 층 수, X 는 엘레베이터로부터 떨어진 거리다.
(흔히 쓰는 아파트 호수랑 같다.)
1. Y (층) 구하기
우리는 H (건물 층수)를 이용해야 하는 것은 알 수 있을 것 같다.
N 번째 손님과 H 는 어떻게 연산하여 층수를 나타낼 수 있을까?
간단하다. N 을 H 로 나눈 나머지 값이 층 수다.
생각해보자.
위 예시처럼 10 번째 손님이면 1 ~ 6 층까지 채워지고 다시 1 층부터 시작하여 4 층에 배정받게 된다.
즉, 10 % 6 을 통해 나머지 값인 4 가 층 수가 되는 것이다.
int Y = N % H;
그런데 유의해야 할 점이 하나 있다.
만약 N = 6 이고, H = 6 이라면?
그럼 나머지가 0 이 되어 0층이 되어버린다.
그러나, 우리가 배정해야 할 층은 6층이다.
N = 12 , H = 6 이여도 마찬가지다.
12 % 6 = 0 으로 0층이라는 값이 나오지만 우리가 배정하고 싶은 층은 6층이다.
즉, N % H = 0 일 때는 H 층이 배정받는 층 수다.
이를 토대로 조건문을 달아보자면 다음과 같아진다.
int Y;
if( N % H == 0 ) {
Y = H;
}
else {
Y = N % H;
}
그리고 호수는 YXX 또는 YYXX 에서 볼 수 있듯이 최소 100의 자릿수부터 시작하므로, Y 에 100을 곱해주면 된다.
즉, 아래 코드와 같이 100을 곱한다.
int Y;
if( N % H == 0 ) {
Y = H * 100;
}
else {
Y = (N % H) * 100;
}
2. X (거리) 구하기
엘레베이터로부터 떨어진 거리는 그럼 어떻게 구해야 할까?
딱 눈에 보이지 않은가?
N 번 째 손님은 건물 층 수(H)로 나눈 몫이 엘레베이터로부터 떨어진 거리다.
그리고 + 1 을 해야한다.
예로들어 N = 3 이고, H = 8 일 때 나눗셈을 하면 몫이 0 이지만, X 는 0 이 아닌 1 부터 시작하기 때문이다.
즉, ( N / H ) + 1 이 X 가 되는 것이다.
int X = (N / H) + 1;
그리고 여기에서도 유의해야 할 점이 하나 있다.
N = 6 이고, H = 6 이라면?
아까 Y 에서도 구했듯이 위의 답은 601 호라는 것은 누구나 안다. 즉, X = 1 이어야 하지만 ( N / H ) + 1 공식에 대입하면 2 라는 답이 나와버린다.
Y에서의 예외와 마찬가지로 X 에서도 N % H = 0 일 때는 + 1 을 더해주지 않고 그냥 ( N / H ) 만 해주면 된다.
즉, 조건문을 추가하면 다음과 같다.
int X;
if( N % H == 0 ) {
X = N / H;
}
else {
X = (N / H) + 1;
}
그리고 Y 와 X 의 예외 조건이 같으므로 하나로 합칠 수 있다.
int X, Y;
if (N % H == 0) {
Y = H * 100;
X = N / H;
}
else {
Y = (N % H) * 100;
X = (N / H) + 1;
}
int XXYY = Y + X; //최종 호수
결과적으로 Y 와 X 를 더해주면 N 번 째 손님이 배정받는 방 번호가 완성된다.
이를 토대로 구조를 짜면 된다.
※ 보면 알겠지만 변수는 원래 H (층), W (한 층의 방 개수), N (N 번째로 오는 손님) 이렇게 3개가 주어진다.
그러나 W 를 쓸 필요가 없다는 것을 알 수 있다.
왜냐하면 백준에서 테스트를 할 때, N 이 H*W 의 값보다 크게 주어지지 않기 때문이다.
즉, 테스트케이스에서 불가능한 예외 케이스를 애초에 넣지 않기 때문에 쓸모가 없다.
- 풀이
- 방법 1
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int T = in.nextInt(); // 테스트 케이스
for(int i = 0; i < T; i++) {
int H = in.nextInt();
int W = in.nextInt(); // 쓸모없는 변수다.
int N = in.nextInt();
if(N % H == 0) {
System.out.println((H * 100) + (N / H));
} else {
System.out.println(((N % H) * 100) + ((N / H) + 1));
}
}
}
}
굳이 X, Y 변수를 따로 선언하지 않고도 가능하기에 바로 연산한 다음에 출력했다.
- 방법 2
BufferedReader 을 쓰는 방식이다.
아무래도 한 줄을 통째로 읽기 때문에 StringTokenizer 나 split() 으로 문자열 분리가 필요하다.
(필자는 StringTokenizer 가 더 편하므로 이를 이용하겠다.)
그리고 반드시 자료형 타입에 주의하자.
또한 테스트 케이스 만큼 출력을 반복적으로 해야하기 때문에 StringBuilder 을 사용하여 출력할 문자열들을 하나로 묶어주고, 마지막에 한 번에 출력하도록 변경했다.
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine()); // 테스트 케이스
for (int i = 0; i < T; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int H = Integer.parseInt(st.nextToken());
st.nextToken(); // W 는 그냥 버린다.
int N = Integer.parseInt(st.nextToken());
if (N % H == 0) {
sb.append((H * 100) + (N / H)).append('\n');
} else {
sb.append(((N % H) * 100) + ((N / H) + 1)).append('\n');
}
}
System.out.print(sb);
}
}
아마 이번 문제는 엄청 쉬워서.. 금방 이해했으리라 본다.
- 성능 차이
위에서 부터 순서대로
채점 번호 : 18915036 - BufferedReader
채점 번호 : 18915031 - Scanner
시간을 보면 BufferedReader 와 Scanner 의 성능차이를 볼 수 있다.
- 정리
매우 쉬운 문제였다.
이 문제 출처가 어디였나 보니까 Daejeon Nationalwide Internet Competition 2014 문제 A 였다.
해당 대회 문제들도 대체로 어렵지 않으니 여러분들도 시간이 된다면 한 번씩 풀어봐도 좋은 문제들인 것 같다.
'JAVA - 백준 [BAEK JOON] > 기본 수학 1' 카테고리의 다른 글
[백준] 10757번 : 큰 수 A+B - JAVA [자바] (23) | 2021.02.01 |
---|---|
[백준] 2775번 : 부녀회장이 될테야 - JAVA [자바] (27) | 2020.04.05 |
[백준] 2869번 : 달팽이는 올라가고 싶다 - JAVA [자바] (38) | 2020.04.01 |
[백준] 1193번 : 분수찾기 - JAVA [자바] (41) | 2020.03.31 |
[백준] 2292번 : 벌집 - JAVA [자바] (17) | 2020.03.29 |