Computer science/알고리즘

[백준, node.js] 11729번 "하노이 탑 이동 순서" 문제 해결방법

남양주개발자 2022. 2. 5. 18:57
728x90
반응형

[백준, node.js] 11729번 "하노이 탑 이동 순서" 문제 해결방법

문제

세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로 옮기려 한다.

  1. 한 번에 한 개의 원판만을 다른 탑으로 옮길 수 있다.
  2. 쌓아 놓은 원판은 항상 위의 것이 아래의 것보다 작아야 한다.

이 작업을 수행하는데 필요한 이동 순서를 출력하는 프로그램을 작성하라. 단, 이동 횟수는 최소가 되어야 한다.

아래 그림은 원판이 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'));
728x90
반응형
그리드형