0281

개발

[백준] 2292번 - 벌집

문제 링크 : https://www.acmicpc.net/problem/2292

문제 탐색하기

1) 문제 분석

  • 육각형으로 이루어진 벌집

  • 중앙의 방 1부터 시작.

  • 이웃하는 방에 돌아가면서 1씩 증가하는 번호로 주소 매핑

count

range

range 개수

1

1

1

2

2~7

6

3

8~19

12

4

20~37

18

5

38~61

24

-> range의 개수가, 6의 배수로 증가하는 것을 확인할 수 있다. 즉, count와 6이라는 숫자를 잘 사용하면 쉽게 풀 수 있을듯 하다.

코드 설계하기

1. 실행 구조

1) 입력값을 읽어서 줄바꿈 기준으로 나눔

2) 첫 번째 줄을 숫자로 변환 (방 번호)

  • N

  • count : 진입 횟수(최소값은 1)

  • range : 현재 범위의 최대값(2부터 시작)

3) 분기

(1) N이 1이면 바로 1 출력

(2) 범위가 N보다 커지기 직전까지 반복

  • 다음 범위의 최대값 계산 (6씩 증가)

  • 진입 횟수 증가

4) 결과 출력

2. 고민이 되었던 부분

: 이번 문제는 복잡한 알고리즘을 요구하지는 않았지만, 범위를 어떻게 계산할지가 가장 큰 고민이었다. 구체적으로는 count 값을 어떤 조건에서 증가시킬지, 또 종료 조건을 어디에 두어야 할지가 핵심이었다.

또한, N이 1일 때는 바로 출력해야 하지만, 그 외의 경우에는 사실상 2부터 탐색을 시작해야 한다는 점을 발견했다.

예를 들어, N=13일 경우를 보자.

  • 처음에 count = 1이고, 시작값은 2이다.

  • 계산식에 따라 2 + (1 × 6) = 8이 나오는데, 이는 N(13)보다 작으므로 count를 증가시켜 다시 반복한다.

  • 그다음은 8 + (2 × 6) = 20인데, 이는 N(13)보다 크므로, 이때 count = 2를 출력하면 되는 것이다.

즉, 범위를 단계별로 확장해가며 N이 속하는 구간을 찾는 방식으로 해결할 수 있었다.

정답 코드

TypeScript
const fs = require('fs');
// 1. 입력값을 읽어서 줄바꿈 기준으로 나눔
const input = fs.readFileSync('/dev/stdin').toString().trim().split("\n");

// 2. 첫 번째 줄을 숫자로 변환 (방 번호)
const N = Number(input[0]);   // 참가자 수
let count = 1; // 3. 진입 횟수(최소값은 1)
let range = 2; // 4. 현재 범위의 최대값(2부터 시작)

// 5. N이 1이면 바로 1 출력
if (N == 1) {
    console.log("1");
} else {
    // 6. 범위가 N보다 커지기 직전까지 반복
    while (range <= N) {
        // 7. 다음 범위의 최대값 계산 (6씩 증가)
        range = range + (6 * count);
        count++; // 8. 진입 횟수 증가
    }

    // 9. 결과 출력
    console.log(count);
}

마무리하며

지난번에 참여한 코딩테스트 13기를 마무리 짓고나서도, 코딩테스트 문제를 조금씩 풀어왔었는데, 현장실습을 준비하면서 잠시 내려놓았던 기간이 조금 길었다고 느껴졌다. 그래서 다시 일주일에 최소 두 문제 이상은 풀고 싶다는 생각이 들어서, 다시 문제를 풀게 되었는데, 생각보다 흥미를 금방 찾을 수 있었다.

이번 문제의 경우에는 특별한 메소드나 알고리즘이 필요한 문제는 아니었지만, 문제를 풀어내기 위한 로직을 고민하고, 이를 풀어내는 과정이 핵심이었다. 풀면서 각 범위가 6의 범위인 것은 발견했지만, 이를 어떻게 더 로직을 구성할 수 있을지에 대해 막힌 점이 있었고, 이를 결국 다른 사람의 풀이를 찾아보면서 힌트를 얻곤 했다. 이렇게 하니깐, 내 힝므로 온전히 푼 느낌이 안 나서 내일은 스스로 풀어보려고 한다.