[프로그래머스][Level2][Java] 하노이의 탑

2022. 8. 26. 17:17·프로그래머스/Level 2

문제

https://school.programmers.co.kr/learn/courses/30/lessons/12946

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이코드

public static int[][] answer;
public static int idx;

public static void hanoi(int n, int first, int mid, int last) { //하노이의 탑 알고리즘
    if (n == 0){
        return;
    }
    hanoi(n - 1, first, last, mid);
    answer[idx][0] = first;
    answer[idx++][1] = last;
    hanoi(n - 1, mid, first, last);
}

public static int[][] solution(int n) {
    answer = new int[(int) Math.pow(2, n) - 1][2];      //총 움직인 횟수를 계산해서 answer 배열로 만들어줌
    idx = 0;
    hanoi(n, 1, 2, 3);
    return answer;
}

 

풀이 코드 설명

우선 이 문제는 풀이코드는 간단하지만 이해하기엔 어려울 수도 있다.

우선 하노이의 탑은 위의 그림과 같이 1번 기둥에 있는 원판들을 3번 기둥으로 옮기는 것이다.

단, 여기서 조건은 

1. 한번에 하나의 원판만 옮길 것

2. 큰 원판이 작은 원판의 위에 있으면 안될 것

이렇게 2가지이다.

 

그럼 이 규칙을 지켜서 위의 그림과 같이 원판이 3개일때, 옮기는 것을 보면

1. 제일 큰 원판을 3번 기둥에 옮기고 나서 다른 원판들을 그 위에 쌓아야 되고

2. 다른 원판들은 3번 기둥을 제외한 다른 원판에 대기하고 있다가 3번 기둥에 차례대로 쌓여야 한다. 

그러면 결국 원판들은

이렇게 1번 기둥에서 2번 기둥으로 옮겨진 뒤, 큰 원판이 3번 기둥으로 이동한 후 그 위로 쌓인다.

그럼 여기서 원판 n개를 ?번 기둥에서 ?기둥으로 옮기는 횟수를 hanoi(n)이라고 가정을 하자

 

hanoi(3)을 구하려면 다음과 같은 순서를 거치면 된다.

1. 원판 2개가 1번 기둥 -> 2번 기둥으로 옮겨간다 => hanoi(2)

2. 제일 큰 원판을 1번 기둥 -> 3번 기둥으로 옮긴다. => (+1)

3. 나머지 원판 2개를 2번 기둥 -> 3번 기둥으로 옮겨간다 => hanoi(2)

즉, hanoi(n) = hanoi(n-1)x2 + 1이 된다.

그래서 위의 점화식을 바탕으로 식을 세워서 계산을 하면

hanoi(n) = 2ⁿ-1이라는 식이 나오고 이것을 이용해서

public static int[][] solution(int n) {
    answer = new int[(int) Math.pow(2, n) - 1][2];      //총 움직인 횟수를 계산해서 answer 배열로 만들어줌
    idx = 0;
    hanoi(n, 1, 2, 3);
    return answer;
}

이 코드에서 answer배열의 길이를 지정해주었다.([원판이 움직인 횟수][경로])

여기서 경로는 ?기둥 -> ??기둥이므로 2로 길이를 지정해주었다.

 

그 다음 위와 같은 원리를 이용해서

public static void hanoi(int n, int first, int mid, int last) { //하노이의 탑 알고리즘
    if (n == 0){
        return;
    }
    hanoi(n - 1, first, last, mid);
    answer[idx][0] = first;
    answer[idx++][1] = last;
    hanoi(n - 1, mid, first, last);
}

위의 메서드를 지정했는데

원판이 움직일 때, ?에서 ??기둥으로 움직이려면 바로 원판을 다 옮기진 못하고 어찌됐든 한번은 다른 기둥에서 잠시 놔두고 위에서 설명한 대로 제일 큰 원판이 ??기둥으로 옮겨진 뒤, 나머지 원판들을 옮겨야 하니까

현재 원판들이 있는 기둥 : first

중간에 잠시 놔두는 기둥 : mid

최종적으로 옮길 기둥 : last

이렇게 지정을 하고 위에서 hanoi(n) = hanoi(n-1)x2 +1이라는 원리를 이용해서

hanoi(n, first, mid, last)

= hanoi(n-1, first, last, mid) => 제일 큰 원판을 last로 옮기기 전에 나머지 원판을 우선 mid에 놔둔다.

(예를 들어 first = 1번, mid = 2번, last = 3번이면 제일 큰 원판을 3번으로 옮기기 전에 나머지 원판을

2번으로 잠시 옮길 것이므로 hanoi(n-1)은 최종목적지를 mid로 설정해주는 것이다.)

 

+ 제일 큰 원판을 first -> last로 옮김

answer[idx][0] = first;
answer[idx++][1] = last;

 

+ hanoi(n-1, mid, first, last) => 제일 큰 원판을 last로 옮긴 뒤, 나머지 원판을 mid에서 last로 다 가져온다.

 

그래서 이러한 방식으로 재귀함수를 이용하면 하노이의 탑을 쉽게 풀 수 있다.

저작자표시 비영리 (새창열림)

'프로그래머스 > Level 2' 카테고리의 다른 글

[프로그래머스][Level2][Java] 삼각 달팽이  (0) 2022.10.31
[프로그래머스][Level2][Java] 줄 서는 방법  (0) 2022.08.26
[프로그래머스][Level2][Java] 멀리 뛰기  (0) 2022.06.14
[프로그래머스][Level2][Java] 구명보트  (0) 2022.06.11
[프로그래머스][Level2][Java] 예상대진표  (0) 2022.06.11
'프로그래머스/Level 2' 카테고리의 다른 글
  • [프로그래머스][Level2][Java] 삼각 달팽이
  • [프로그래머스][Level2][Java] 줄 서는 방법
  • [프로그래머스][Level2][Java] 멀리 뛰기
  • [프로그래머스][Level2][Java] 구명보트
BvrPark
BvrPark
코드 퍼즐과 개발 일상
  • BvrPark
    비버의 개발 일지
    BvrPark
  • 전체
    오늘
    어제
    • 분류 전체보기 (121)
      • JAVA (7)
        • 메서드 외울 것 (2)
      • 프로그래머스 (56)
        • 총 풀이 코드(깃허브) (1)
        • Level 1 (22)
        • Level 2 (33)
      • 백준 알고리즘(단계 별) (16)
        • 총 풀이 코드(깃허브) (1)
        • 1. 입출력과 사칙연산 (2)
        • 2. if 문 (2)
        • 3. for문 (1)
        • 4. while문 (2)
        • 5. 1차원 배열 (3)
        • 6. 함수 (1)
        • 7. 문자열 (1)
        • 8. 기본수학 1 (3)
      • 백준 알고리즘(solved.ac) (9)
        • 총 풀이 코드(깃허브) (1)
        • class2 (8)
      • LeetCode 문제 풀이 (4)
        • 총 풀이 코드(깃허브) (1)
        • Easy (3)
      • 코드업 알고리즘 (7)
      • git과 github사용법 (4)
      • html, css, javaScript (2)
      • 프로젝트 (11)
        • 순수 Java 프로젝트 (2)
        • 쇼핑몰 프로젝트 (2)
        • 게시판 프로젝트 (5)
        • 근태관리 프로젝트 (2)
      • 커피타임 (2)
        • 2023년 (2)
        • 2024년 (0)
  • 블로그 메뉴

    • 링크

      • 포트폴리오
      • 깃허브
    • 공지사항

    • 인기 글

    • 태그

    • 최근 댓글

    • 최근 글

    • Designed By정상우
    BvrPark
    [프로그래머스][Level2][Java] 하노이의 탑
    상단으로

    티스토리툴바