문제
세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로 옮기려 한다.
- 한 번에 한 개의 원판만을 다른 탑으로 옮길 수 있다.
- 쌓아 놓은 원판은 항상 위의 것이 아래의 것보다 작아야 한다.
이 작업을 수행하는데 필요한 이동 순서를 출력하는 프로그램을 작성하라. 단, 이동 횟수는 최소가 되어야 한다.
아래 그림은 원판이 5개인 경우의 예시이다.
예제 입력 & 출력
입력
첫째 줄에 첫 번째 장대에 쌓인 원판의 개수 N (1 ≤ N ≤ 20)이 주어진다.
출력
첫째 줄에 옮긴 횟수 K를 출력한다.
두 번째 줄부터 수행 과정을 출력한다. 두 번째 줄부터 K개의 줄에 걸쳐 두 정수 A B를 빈칸을 사이에 두고 출력하는데, 이는 A번째 탑의 가장 위에 있는 원판을 B번째 탑의 가장 위로 옮긴다는 뜻이다.
소스코드
정말 유명한 문제 중 하나인 하노이탑 알고리즘. 사실 재귀 함수를 활용한 문제인 것은 알고리즘 공부를 시작한 사람들은 무조건 파악 가능한 문제긴 하나 머릿속에서 재귀 과정을 그려내기엔 쉽지 않은 것 같다.
알고리즘 구현 방법은 아래와 같다.
1. 원반이 한 개면 그냥 옮기면 끝이다(종료 조건).
2. 원반이 n개일 때 1) 1번 기둥에 있는 n개 원반 중 n-1개를 2번 기둥으로 옮긴다(3번 기둥을 보조 기둥으로 사용). 2) 1번 기둥에 남아 있는 가장 큰 원반을 3번 기둥으로 옮긴다.
3) 2번 기둥에 있는 n-1개 원반을 다시 3번 기둥으로 옮긴다(1번 기둥을 보조 기둥으로 사용).
const fs = require('fs');
let n = fs.readFileSync('./dev/stdin').toString();
n = Number(n);
const rseult = [];
function hanoi(n, from, to, via) {
if (n === 1) return rseult.push(`${from} ${to}`);
hanoi(n-1, from, via, to);
rseult.push(`${from} ${to}`);
hanoi(n-1, via, to, from);
}
console.log(BigInt(Math.pow(2, n) - 1).toString());
hanoi(n, 1, 3, 2);
console.log(rseult.join('\n'));
'Computer science > 알고리즘' 카테고리의 다른 글
[백준, node.js] 2004번 "조합 0의 개수" 문제 해결방법 (3) | 2022.02.13 |
---|---|
[백준, node.js] 2133번 "타일 채우기" 문제 해결방법 (0) | 2022.02.05 |
[백준, node.js] 9461번 "파도반 수열" 문제 해결방법 (0) | 2022.02.04 |
이진 탐색(Binary Search) 알고리즘 개념 이해 및 예제 feat. Javascript (0) | 2022.02.04 |
[백준, node.js] 2225번 "합분해" 문제 해결방법 (1) | 2022.02.03 |
이 포스팅은 쿠팡파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.