(C언어) 백준 2292. 벌집

문제

etc-image-0

위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 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;
}