일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- 리얼클래스
- 네트워크 관리사 2급 실기
- SSAFY
- 네트워크 관리사 2급
- 네트워크 관리사
- 우테코
- IT 동향
- it 이슈
- 카카오
- KT
- html
- Java
- 코딩테스트 연습
- 구글
- SSAFYcial
- 싸피
- 인앱결제
- 코테
- 코딩테스트
- 신문스크랩
- 신문 스크랩
- 백준위
- 백준
- python
- IT 트렌드
- it 뉴스
- SSAFY 7기
- 프로그래머스
- java 객체지향 프로그래밍
- 싸피셜
Archives
- Today
- Total
개발자일걸요..?
11729번 하노이 탑 이동순서 본문
728x90
반응형
문제 링크 : www.acmicpc.net/problem/11729
하노이 탑의 기본 규칙
- 한 번에 하나의 원판만 옮길 수 있다.
- 큰 원판이 작은 원판 위에 있어서는 안 된다.
예를 들어 원반이 3개와 막대 3개가 존재할 때, 알고리즘은
1,2번 원반 2개를 A->B로 이동. 이때 C 경유 가능
(1번 원반을 A->C로 이동.
2번 원반을 A->B로 이동.
1번 원반을 C->B로 이동.)
3번 원반을 A->C로 이동.
1,2번 원반 2개를 B->C로 이동. 이때 A 경유 가능
(1번 원반을 B->A로 이동.
2번 원반을 B->C로 이동.
1번 원반을 A->C로 이동.)
이다. 이를 코드로 바꿔보면 아래와 같다.
#include <iostream>
#include <vector>
using namespace std;
vector<pair<int, int>> list;
void move(char from, char to) {
int start = 0;
int finish = 0;
if (from == 'A') start = 1;
else if (from == 'B') start = 2;
else if (from == 'C') start = 3;
if (to == 'A') finish = 1;
else if (to == 'B') finish = 2;
else if (to == 'C') finish = 3;
list.push_back(make_pair(start, finish));
}
void hanoi(int now, char start, char via, char finish) {
if (now == 1) {
move(start, finish);
return;
}
else {
hanoi(now - 1, start, finish, via); // 이동해야하는 n원반위 n-1개의 원반을 경유지로 이동
move(start, finish); // n 원반을 종착지로 이동
hanoi(now - 1, via, start, finish); // via에 있는 n-1개의 원반을 종착지로 이동
}
}
int main() {
int N = 0;
cin >> N;
hanoi(N, 'A', 'B', 'C');
cout << list.size() << "\n";
for (unsigned int i = 0; i < list.size(); i++) {
cout << list[i].first << " " << list[i].second << "\n";
}
}
아래 코드는 위의 코드를 좀 더 간략화시킨 것이다.
1. 전역 변수를 없애고 하노이탑의 이동 횟수 출력 => 소요시간 감소
2. 막대를 char 대신 int로 지정함으로서 변환 과정(char->int) 생략
#include <iostream>
#include <cmath>
using namespace std;
void move(int from, int to) {
cout << from << " " << to << "\n";
}
void hanoi(int now, int start, int via, int finish) {
if (now == 1) {
move(start, finish);
return;
}
else {
hanoi(now - 1, start, finish, via); // 이동해야하는 n원반위 n-1개의 원반을 경유지로 이동
move(start, finish); // n 원반을 종착지로 이동
hanoi(now - 1, via, start, finish); // via에 있는 n-1개의 원반을 종착지로 이동
}
}
int main() {
int N = 0;
cin >> N;
cout << (long long int) pow(2, N) - 1 << "\n";
hanoi(N, 1, 2, 3);
}
반응형
'알고리즘코딩 > Baekjoon Online Judge' 카테고리의 다른 글
7568번 덩치 (0) | 2021.02.01 |
---|---|
1436번 영화 감독 숌 (0) | 2021.02.01 |
2231번 분해합 (0) | 2021.01.31 |
2798번 블랙잭 (0) | 2021.01.31 |
2447번 별찍기 (0) | 2021.01.30 |
Comments