문제
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 호를 더 선호한다.
여러분이 작성할 프로그램은 초기에 모든 방이 비어있다고 가정하에 이 정책에 따라 N 번째로 도착한 손님에게 배정될 방 번호를 계산하는 프로그램이다. 첫 번째 손님은 101 호, 두 번째 손님은 201 호 등과 같이 배정한다. 그림 1 의 경우를 예로 들면, H = 6이므로 10 번째 손님은 402 호에 배정해야 한다.
입력
프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수를 포함하고 있으며 각각 호텔의 층 수, 각 층의 방 수, 몇 번째 손님인지를 나타낸다(1 ≤ H, W ≤ 99, 1 ≤ N ≤ H × W).
출력
프로그램은 표준 출력에 출력한다. 각 테스트 데이터마다 정확히 한 행을 출력하는데, 내용은 N 번째 손님에게 배정되어야 하는 방 번호를 출력한다.
예제 입력 1
2
6 12 10
30 50 72
예제 출력 1
402
1203
예상 풀이 방법
일단 테스트 케이스 T를 받아서 T만큼의 for문 안에서 문제를 펼친다.
배열을 사용하여 x와 y를 펼치고
방 번호가 YYXX 번이라고 하여 푼다.
101 201 301 순으로 배정하다가 꼭대기층이 되면 다시 1층으로 돌려야하기에
몫 구하기로 N에서 H를 나누면 몫이 나오는데 그 몫을 결과값에 쓸 a로 지정한다. (층수)
그리고 나머지를 구해야되는데 이용객 번째 수 N을 H(층수)로 나눈 나머지만큼 돌릴거니까 수가 나온다.
이걸 b라고 지정한다.
그러면 몫과 나머지를 구하는 간단한 문제가 되는데
마지막에 printf를 써서 a, b 를 출력하면 된다.
1차 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0){
a = H;
b = N / H;
}
printf("%d %d", a, b);
}
return 0;
}
1차 결과
디버그 에러
1차 진단
초기화되지 않은 b를 사용했다고 떠서 b를 0으로 지정할까 했는데
변수가 그럼 항상 0으로 끝나서 나올 것 같았다.
변수 선언 위치를 옮기자니 printf까지 b값을 끌고오지 못하는 문제가 있다.
그럼 printf의 위치를 옮기자니 그것도 마찬가지로 어림도 없다.
b가 a값이 H로 바뀐 이후에 연산하고싶은데 굳이 if문에 들어갈 이유가 없다.
그럼 if문 밖으로 b를 꺼내면 된다.
2차 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0) {
a = H;
}
b = N / H;
printf("%d %d", a, b);
}
return 0;
}
2차 결과
2
6 12 10
4 1
30 50 72
12 2
2차 진단
뭐가 되어가고있긴하다. 근데 층 수는 맞는데 호실이 0부터 시작해서 아무래도 1이 모자르다.
마지막에 +1하면 될거같긴하다.
근데 하기전에 생각난건데 층이 5개고 층마다 5개면
305호 계산될 때 306호 출력되는거아닌가싶은 오묘한 감정이 든다.
if문 달다가 알게된건데 if (b == W) 와 관련해서 뭔가를 달게되면 그럼 앞자리들은 어떡하나 싶어졌다.
그럼 마지막에 와서 뭔가를 바꾸는 게 아니라 어차피 0부터 했으니까 걍 + 1 하면 될 것 같다.
그리고 몇 자리수로 나타낼건지는 %02d로 된다고 했었다. 그거 써야겠다.
3차 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0) {
a = H;
}
b = N / H;
printf("%d%02d\n", a, b + 1);
}
return 0;
}
3차 결과
2
6 12 10
402
30 50 72
1203
맞았다.
하지만 백준에 제출 시 오답처리
3차 진단
분명 맞게 나오긴 하는데 역시나였다.
1
5 5 25 를 넣으면
5 x 5 호텔에 25번째 손님이라 505호가 나와야되는데 506호가 나와서 틀린 것 같다.
첫 손님 101호는 잘 나오는데 무조건 +1을 주는 조건때문에 틀려먹은 것 같다.
3 x 3을 기준으로 전부 돌렸을 때 나오는 문제점을 다 모아보기로 했다.
- 첫 번째 손님이 100호실을 받는 문제 (두 번째 손님 200번 3번째 300번 모두 동일)
- 네 번째 손님이 101호실을 받는 문제 (전부 동일)
- 아홉 번째 손님이 303호실을 받는 것은 문제되지 않음.
그러면 자꾸 2호실이 비는 문제가 나타나는데
맨 뒤에 3호실을 끌어올 게 아니라
0호실 1호실이 나오는 문제에서 +1을 하는 것이 맞고
그러면 전부 +1 처리를 해주고
만약 끝번호 방이라면 -1을 해주는 게 맞다.
그럼 b값을 N / H - 1로 정의하고
if를 더 달아서 N % H가 0일 경우 ( 해당 층의 끝번호 자리일 경우 )
다시 b에 -1을 해주면 된다.
4차 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0) {
a = H;
}
b = N / H + 1;
if (N % H == 0) {
b -= 1;
}
printf("%d%02d\n", a, b);
}
return 0;
}
4차 결과
2
6 12 10
402
30 50 72
1203
백준 채점 결과

미흡했던 점
초반에 구성하는 방법은 잘 파고들었으나 if문의 종결과 지역변수 선언이 어디까지인지 알지 못해서 시간을 많이 허비함
변수(100호 출력)를 발견하지 못하고 직접 돌려보고나서야 알았음
개선 방안
이건 외우는 것도 아니고 그냥 많이 봐야될 것 같다.
반복문을 0부터 쓰는지 1부터 쓰는지는 많이 해봐서 숙달된 것 같은데
for문 내에서 주어진 값을 그대로 계산에 사용하다보니 조금 헷갈린 것 같다.
최종 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0) {
a = H;
}
b = N / H + 1;
if (N % H == 0) {
b -= 1;
}
printf("%d%02d\n", a, b);
}
return 0;
}
'C > BaekJoon' 카테고리의 다른 글
[C] 백준 10798 - 세로읽기 | BaekJoon (0) | 2023.08.04 |
---|---|
[C] 백준 9610 - 사분면 | BaekJoon (0) | 2023.08.02 |
[C] 백준 2748 - 피보나치 수2 | BaekJoon (0) | 2023.08.02 |
[C] 백준 2747 - 피보나치 수 | BaekJoon (0) | 2023.08.02 |
[C] 백준 1977 - 완전제곱수 | BaekJoon (0) | 2023.08.01 |
문제
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 호를 더 선호한다.
여러분이 작성할 프로그램은 초기에 모든 방이 비어있다고 가정하에 이 정책에 따라 N 번째로 도착한 손님에게 배정될 방 번호를 계산하는 프로그램이다. 첫 번째 손님은 101 호, 두 번째 손님은 201 호 등과 같이 배정한다. 그림 1 의 경우를 예로 들면, H = 6이므로 10 번째 손님은 402 호에 배정해야 한다.
입력
프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수를 포함하고 있으며 각각 호텔의 층 수, 각 층의 방 수, 몇 번째 손님인지를 나타낸다(1 ≤ H, W ≤ 99, 1 ≤ N ≤ H × W).
출력
프로그램은 표준 출력에 출력한다. 각 테스트 데이터마다 정확히 한 행을 출력하는데, 내용은 N 번째 손님에게 배정되어야 하는 방 번호를 출력한다.
예제 입력 1
2
6 12 10
30 50 72
예제 출력 1
402
1203
예상 풀이 방법
일단 테스트 케이스 T를 받아서 T만큼의 for문 안에서 문제를 펼친다.
배열을 사용하여 x와 y를 펼치고
방 번호가 YYXX 번이라고 하여 푼다.
101 201 301 순으로 배정하다가 꼭대기층이 되면 다시 1층으로 돌려야하기에
몫 구하기로 N에서 H를 나누면 몫이 나오는데 그 몫을 결과값에 쓸 a로 지정한다. (층수)
그리고 나머지를 구해야되는데 이용객 번째 수 N을 H(층수)로 나눈 나머지만큼 돌릴거니까 수가 나온다.
이걸 b라고 지정한다.
그러면 몫과 나머지를 구하는 간단한 문제가 되는데
마지막에 printf를 써서 a, b 를 출력하면 된다.
1차 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0){
a = H;
b = N / H;
}
printf("%d %d", a, b);
}
return 0;
}
1차 결과
디버그 에러
1차 진단
초기화되지 않은 b를 사용했다고 떠서 b를 0으로 지정할까 했는데
변수가 그럼 항상 0으로 끝나서 나올 것 같았다.
변수 선언 위치를 옮기자니 printf까지 b값을 끌고오지 못하는 문제가 있다.
그럼 printf의 위치를 옮기자니 그것도 마찬가지로 어림도 없다.
b가 a값이 H로 바뀐 이후에 연산하고싶은데 굳이 if문에 들어갈 이유가 없다.
그럼 if문 밖으로 b를 꺼내면 된다.
2차 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0) {
a = H;
}
b = N / H;
printf("%d %d", a, b);
}
return 0;
}
2차 결과
2
6 12 10
4 1
30 50 72
12 2
2차 진단
뭐가 되어가고있긴하다. 근데 층 수는 맞는데 호실이 0부터 시작해서 아무래도 1이 모자르다.
마지막에 +1하면 될거같긴하다.
근데 하기전에 생각난건데 층이 5개고 층마다 5개면
305호 계산될 때 306호 출력되는거아닌가싶은 오묘한 감정이 든다.
if문 달다가 알게된건데 if (b == W) 와 관련해서 뭔가를 달게되면 그럼 앞자리들은 어떡하나 싶어졌다.
그럼 마지막에 와서 뭔가를 바꾸는 게 아니라 어차피 0부터 했으니까 걍 + 1 하면 될 것 같다.
그리고 몇 자리수로 나타낼건지는 %02d로 된다고 했었다. 그거 써야겠다.
3차 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0) {
a = H;
}
b = N / H;
printf("%d%02d\n", a, b + 1);
}
return 0;
}
3차 결과
2
6 12 10
402
30 50 72
1203
맞았다.
하지만 백준에 제출 시 오답처리
3차 진단
분명 맞게 나오긴 하는데 역시나였다.
1
5 5 25 를 넣으면
5 x 5 호텔에 25번째 손님이라 505호가 나와야되는데 506호가 나와서 틀린 것 같다.
첫 손님 101호는 잘 나오는데 무조건 +1을 주는 조건때문에 틀려먹은 것 같다.
3 x 3을 기준으로 전부 돌렸을 때 나오는 문제점을 다 모아보기로 했다.
- 첫 번째 손님이 100호실을 받는 문제 (두 번째 손님 200번 3번째 300번 모두 동일)
- 네 번째 손님이 101호실을 받는 문제 (전부 동일)
- 아홉 번째 손님이 303호실을 받는 것은 문제되지 않음.
그러면 자꾸 2호실이 비는 문제가 나타나는데
맨 뒤에 3호실을 끌어올 게 아니라
0호실 1호실이 나오는 문제에서 +1을 하는 것이 맞고
그러면 전부 +1 처리를 해주고
만약 끝번호 방이라면 -1을 해주는 게 맞다.
그럼 b값을 N / H - 1로 정의하고
if를 더 달아서 N % H가 0일 경우 ( 해당 층의 끝번호 자리일 경우 )
다시 b에 -1을 해주면 된다.
4차 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0) {
a = H;
}
b = N / H + 1;
if (N % H == 0) {
b -= 1;
}
printf("%d%02d\n", a, b);
}
return 0;
}
4차 결과
2
6 12 10
402
30 50 72
1203
백준 채점 결과

미흡했던 점
초반에 구성하는 방법은 잘 파고들었으나 if문의 종결과 지역변수 선언이 어디까지인지 알지 못해서 시간을 많이 허비함
변수(100호 출력)를 발견하지 못하고 직접 돌려보고나서야 알았음
개선 방안
이건 외우는 것도 아니고 그냥 많이 봐야될 것 같다.
반복문을 0부터 쓰는지 1부터 쓰는지는 많이 해봐서 숙달된 것 같은데
for문 내에서 주어진 값을 그대로 계산에 사용하다보니 조금 헷갈린 것 같다.
최종 코드
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int H, W, N, a, b;
scanf("%d %d %d", &H, &W, &N);
a = N % H;
if (a == 0) {
a = H;
}
b = N / H + 1;
if (N % H == 0) {
b -= 1;
}
printf("%d%02d\n", a, b);
}
return 0;
}
'C > BaekJoon' 카테고리의 다른 글
[C] 백준 10798 - 세로읽기 | BaekJoon (0) | 2023.08.04 |
---|---|
[C] 백준 9610 - 사분면 | BaekJoon (0) | 2023.08.02 |
[C] 백준 2748 - 피보나치 수2 | BaekJoon (0) | 2023.08.02 |
[C] 백준 2747 - 피보나치 수 | BaekJoon (0) | 2023.08.02 |
[C] 백준 1977 - 완전제곱수 | BaekJoon (0) | 2023.08.01 |