[풀이]백준 풀이(XV/11729 등)
문제풀이
[RE]하노이의 탑 이동순서(11729, 시뮬레이션)
- 세 개의 장판이 있고 첫 번째 장판에 반경이 서로 다른 n개의 원판이 쌓여있다.
- 쌓인 원판은 크기순으로 쌓여있다.
- 한 번에 한 개의 원판만을 다른 탑으로 옮길 수 있다.
- 쌓아놓은 원판은 항상 위의 것이 아래의 것 보다 작아야 한다.
위 작업을 수행하는데 필요한 이동 순서를 출력하는 프로그램을 작성하다. (단, 이동 횟수는 최소)
풀이
하노이의 탑 문제는 풀이가 정해져있고 이걸 생각하는 것 보다 찾는게 빠르므로 풀이를 봤다.
- 재귀함수 형태를 사용한다.
- 장판을 A, B, C장판이라고 한다.
- N개의 원반이 있다고 할 때, 작은원반 N-1개를 (A->B)이동.
- 남은 가장 큰 원반을 (A->C) 이동.
- 반복.
n개의 탑을 옮기기 위해서는 등비수열이므로 O(2^N)이 나온다.
잘못된 풀이
stack이나 queue를 쓰겠다고 헛짓을 했다… 문제에서 원하는 정답을 출력하기 어려움
#include <iostream>
#include <stack>
#define END 3
using namespace std;
int n;
stack<int> floor[3];
//(1 to 2) or (2 to 1)에서
void move(int from, int to){
//3번 바닥에 모든 원판이 이동할 때까지 계속 재귀
int size = floor[END].size();
while(size==n){
//스택이니까 맨 마지막에 넣은걸 먼저 3번으로 얹자!
floor[END].push(floor[from].top());
floor[from].pop();
//옮길게 없거나 사이즈가 꽉차면 끝내고
if(floor[from].empty() || floor[END].size()==n) return;
while(!floor[from].empty()){
floor[to].push(floor[from].top());
floor[from].pop();
}
move(to, from);
}
return;
//마지막 남은 것을 3번으로 옮긴다.
}
int main(){
cin >> n;
//a바닥에 1~n까지 집어넣는다.
for(int i=1; i<=n; i++){
//a
floor[0].push(i);
}
move(0,1);
}
풀이
위에서 부터 한 칸씩 빼내야 하는 거라 좀 얘기가 다르다.
#include <iostream>
#include <vector>
using namespace std;
int N;
vector<pair<int, int>> v;
void Hanoi(int num, int from, int by, int to)
{
if (num == 1)
v.push_back({ from, to });
else
{
Hanoi(num - 1, from, to, by);
v.push_back({ from, to });
Hanoi(num - 1, by, from, to);
}
}
int main(void)
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N;
Hanoi(N, 1, 2, 3);
cout << v.size() << "\n";
for (int i = 0; i < v.size(); i++){
cout << v[i].first << " " << v[i].second << "\n";
}
return 0;
}
댓글남기기