https://www.acmicpc.net/problem/2292
2292번: 벌집
위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 1부터 시작해서 이웃하는 방에 돌아가면서 1씩 증가하는 번호를 주소로 매길 수 있다. 숫자 N이 주어졌
www.acmicpc.net
문제

위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 1부터 시작해서 이웃하는 방에 돌아가면서 1씩 증가하는 번호를 주소로 매길 수 있다. 숫자 N이 주어졌을 때, 벌집의 중앙 1에서 N번 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나가는지(시작과 끝을 포함하여)를 계산하는 프로그램을 작성하시오. 예를 들면, 13까지는 3개, 58까지는 5개를 지난다.
입력
첫째 줄에 N(1 ≤ N ≤ 1,000,000,000)이 주어진다.
출력
입력으로 주어진 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나는지 출력한다.
예제 입력 1
13
예제 출력 1
3
내풀이
벌집의 개수가 1 → 6 → 12 → 18 → ··· 이렇게 6의 배수로 증가하는 것을 알 수 있다.
이 때, 벌집 하나 하나를 방이라고 부르자.
- 1번째 방을 1겹
- 2 ~ 7까지 방을 2겹
- 8 ~ 19까지 방을 3겹
- 20 ~ 37까지 방을 4겹
- ···
위와 같이 생각한다면, 주어진 숫자 N이 몇 번째 겹이 있는지 알 수 있다.
이를 활용하여 코드를 짜보자.
N = int(input())
num_beehive = 1 # 방의 개수
cnt = 1 # 겹의 개수
while N > num_beehive : # 방의 개수가 N이랑 같아질 때까지
num_beehive += 6 * cnt # 방의 개수는 6의 배수로 늘어난다.
cnt += 1 # + 1겹
print(cnt)
수학적으로 푸는 방법
수학적으로 생각한다면 이는 '계차수열'임을 알 수 있다.
1 → +6 → 7 → +12 → 19 → +18 → 37 → ···
6 → 6x2 → 12 → 6x3 → 18 → ···
아래 수열의 일반항 b_n을 먼저 구해보자.
이는 첫 항이 6이고 공차가 6인 등차수열이므로 일반항 b_n = 6 + (n - 1)*6 = 6n
b_n을 이용하여 원래의 수열의 일반항 a_n을 구해보자.
a_n = 1 + 6( (n-1)(n) / 2 ) = 1 + 3n(n-1)
따라서 이 일반항을 이용하여서도 코드를 짤 수가 있다.
N = int(input())
cnt = 1
while N > (3*(cnt**2) - 3*cnt + 1):
cnt += 1
print(cnt)