2022. 11. 25. 02:18ㆍGold/Gold V
오랜만에 골드 문제의 풀이와 함께 돌아왔다.
분할 정복이라는 새로운 개념을 배우고 나서 하루에만 열 개 가까이 골드 문제를 처리했다.
한 방법을 새로이 알게 되면 아무래도 그 방법을 이용해 풀 수 있는 문제는 전부 도전해 보는 편이라.
그럼 본격적으로 풀이에 돌입해 보자.
문제
비요뜨는 지금 강 앞에 서 있다. 강 위에는 징검다리가 놓여 있다.
징검다리는 비요뜨가 있는 방향에서부터 반대 방향까지 차례로 1번, 2번, ..., N번의 번호를 가지고 있다.
비요뜨는 1번 징검다리 위에 올라갔다. 그리고 아래 두 가지 규칙을 지키며 징검다리를 건너려고 한다.
- 1 ≤ X ≤ N 인 임의의 정수 X에 대해, 현재 있는 징검다리의 번호를 i번이라고 할 때 i+X번 징검다리로 뛸 수 있다.
- N번째 징검다리를 지나쳐선 안 되고, 정확히 도착해야 한다.
비요뜨는 자신의 특기인 코딩을 살리기 위해 노트북을 켰지만, 실수로 노트북을 강에 빠뜨리고 말았다.
비요뜨를 대신해 강을 건너는 경우의 수를 구해 주자!
입력
첫 번째 줄에 테스트 케이스의 수 T가 주어진다. (1 ≤ T ≤ 1000)
각 테스트 케이스는 한 줄로 구성되며, 징검다리의 개수를 의미하는 N이 주어진다. (1 ≤ N ≤ \(10^9\))
예제 입력)
1
4
출력
각 테스트 케이스에 대해, 한 줄에 하나씩 규칙을 만족하면서 징검다리를 건너는 경우의 수를 \(10^9+7\)로 나눈 나머지를 출력한다.
예제 출력)
4
강을 건너는 방법은, (1 → 4), (1 → 2 → 4), (1 → 3 → 4), (1 → 2 → 3 → 4)의 4가지이다.
내 코드
c = 1000000007
def power(b):
if b<2: return (2**b)%c
else:
d = b//2
return ((power(d))**2)%c if b%2 == 0 else (2*(power(d))**2)%c
for _ in range(int(input())):
N = int(input())
print(1 if N<3 else power(N-2))
우선 경우의 수부터 살펴보자.
징검다리를 건너려면 1번과 N번 돌은 꼭 밟아야 하니 N=1, 2일 때는 건너는 방법이 유일할 것이다. 다른 방법이 전혀 없으니까.
대신 N이 3 이상일 경우에는 2번, ..., N-1번 돌을 밟거나, 밟지 않는 식으로 건너야만 하므로 경우의 수가 정확히 \(2^{N-2}\)가지가 되어야 할 것이다.
각 2번, ..., N-1번의 N-2개의 돌에 대해서 각각 밟거나, 밟지 않는 두 가지 경우의 수가 있으니 말이다.
power(b)는 2의 b제곱을 c(\(10^9+7\))로 나눈 나머지를 뱉는 함수이다.
우선 b가 2보다 작을 경우 당연히 2의 b제곱을 뱉어도 된다. b가 사실 어느 정도 작으면 그냥 뱉어도 되고.
그러나 여기 문제에서는 N이 무려 10억까지 커진다. 이 정도 되면 연산을 하지 않더라도 메모리를 기가바이트 단위로 잡아먹게 된다.
그럴 때를 대비하여 만들어 놓은 것이 바로 power(b).
만약 b가 2x 꼴일 경우 power(x)*power(x)을 c로 나눈 나머지가 곧 power(b)를 c로 나눈 나머지와 같을 것이고, b가 2x+1꼴일 경우에는 2*power(x)*power(x)를 c로 나눈 나머지가 곧 power(b)를 c로 나눈 나머지와 같을 것이다.
남은 것은 power(N-2)를 N이 3 이상일 때, N이 3보다 작을 때는 1을 출력하게 하도록 프로그래밍하면 끝.
이로서 18291번의 풀이를 마친다.
'Gold > Gold V' 카테고리의 다른 글
BOJ 9764 - 서로 다른 자연수의 합 (Python3) (0) | 2023.10.31 |
---|---|
BOJ 27087 - 직육면체 (Python3) (0) | 2023.01.02 |
BOJ 2447 - 별 찍기 - 10 (Python3) (1) | 2022.12.17 |
BOJ 15717 - 떡파이어 (Python3) (0) | 2022.12.04 |
BOJ 11758 - CCW (Python3) (0) | 2022.11.18 |