문제
위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 1부터 시작해서 이웃하는 방에 돌아가면서 1씩 증가하는 번호를 주소로 매길 수 있다. 숫자 N이 주어졌을 때, 벌집의 중앙 1에서 N번 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나가는지(시작과 끝을 포함하여)를 계산하는 프로그램을 작성하시오. 예를 들면, 13까지는 3개, 58까지는 5개를 지난다.
입력
첫째 줄에 N(1 ≤ N ≤ 1,000,000,000)이 주어진다.
출력
입력으로 주어진 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나는지 출력한다.
구상
1 까지는 1칸 걸린다.
2 부터 7(1+6) 까지는 2칸 걸린다.
8부터 19(1+6+12) 까지는 3칸 걸린다.
20부터 37(1+6+12+18) 까지는 4칸 걸린다.
두 번째 항부터는 초항이 6이고, 공차가 6인 등차수열로 증가한다.
이 등차수열을 식으로 나타내보자.
초항과 공차가 모두 6이므로 $a=d=6$일 때
일반항은 $1+\frac{n(2a+(n-1)a)}{2}$이다. 이 계산은 함수 seq(n)에서 실행한다.
n이 0일 때 1,
n이 1일 때 7,
n이 2일 때 19,
n이 3일 때 37이다.
입력받은 room이 seq(n)보다 크거나 같고, seq(n+1)보다 작거나 같다면, 즉
if (seq(n) <= room && room <= seq(n + 1))
이라면 n+1은 이동해야 하는 칸 수가 된다.
예를 들어 room이 15라 하자.
n=1일 때 seq(1)=7이고, seq(2)=19이다. 15에 도달하려면 2칸을 움직여야 한다. 이는 n+1과 같다.
n을 점차 증가시키며room이 조건에 부합하는지 검사하고, 부합하면 check를 TRUE로 바꾸어 반복문을 빠져나오도록 한다.
room이 1일 때는 따로 출력하도록 한다.
코드
#define TRUE 1
#define FALSE 0
#include <stdio.h>
int seq(int n);
int main(void)
{
int room;
scanf("%d", &room);
int check = FALSE; //while문이 실행될 수 있도록 초기 check값은 FALSE
int n = 0;
if (room == 1) check = TRUE; //1은 계산할 필요 없으므로 TRUE로 설정
while (check != TRUE) {
if (seq(n) <= room && room <= seq(n + 1)) {
check = TRUE;
}
n++;
}
if (room == 1) printf("1");
else printf("%d", n + 1);
return 0;
}
int seq(int n) //수열 계산
{
int a = 6;
int res = 1 + ((n * (2 * a + (n - 1) * a)) / 2);
return res;
}
'프로그래밍 > Baekjoon' 카테고리의 다른 글
(파이썬)백준 1065. 한수 (0) | 2020.08.29 |
---|---|
(파이썬)백준 8958. OX퀴즈 (0) | 2020.08.28 |
(C언어)백준 1712. 손익분기점 (0) | 2020.08.25 |
(C언어)백준 4344. 평균은 넘겠지 (0) | 2020.08.25 |
(C언어) 백준 1546. 평균 (0) | 2020.08.21 |