하노이 탑 기둥이4개;
글쓴이: izlley / 작성시간: 일, 2003/03/30 - 7:06오전
하노이 탑 을 만들시 질문입니다..(기둥이 3개가 아니라 4개임)
다시말해, 1번기둥에 있는 원판들을 2,3번기둥을 거쳐서 4번으로 옮기는것 입니다. (꼭 2,3번기둥을 거칠 필요는 없습니다)
제가 짜긴짰는데 너무 불필요한 이동이 많이 생겨서 여러분께 질문드리는 것입니다. 좀더 효율적으로 이동할려면 어떻게 해야 하나요? --a
요기서 move함수는 계속 리커젼을 돌면서 원판을 이동시킵니다.
Quote:
void move(int n, int a, int b, int c, int d, int* count)
{ /* n은 원판의 개수, a는 현재축, b는 옮길 목표, c와 d는 경유 축 */
if(n>0) //count는 이동 횟수 카운터
{
move(n-1, a, c, d, b, count); //a->c
cout <<a<<" 번에서 " <<b<<" 번으로 한 장의 디스크를 옮깁니다."<<endl;
(*count)++;
move(n-1, c, d, a, b, count); //c->d
move(n-1, d, b, a, d, count); //d->b
}
}main()
{
...
disks 입력받음.. //옮길 원판의 개수
int count=0;
move(disks, 1, 4, 2, 3, &count); //1->4로 옮기는게 목표
... //2,3번은 경유 기둥
}리커젼 정말 골때리는 군요 ㅜㅜ; :oops:
답변 부탁 드립니다@ :wink:
Forums:
하노이 탑엔 여러 변종들이 있는데 ..그 변종들은 대체로 좀 수학적인
하노이 탑엔 여러 변종들이 있는데 ..
그 변종들은 대체로 좀 수학적인 능력도 필요하고 ..
머리아프죠 .. -_-a
적으신 방법으로 해서는
기둥이 3개 있을때보다도 이동횟수가 많을것 같네요 ..
기둥이 4개일때는 대개,
(n개를 a에서 b,c를 경유해서 d로 보낸다고 하면)
a -> b 로 k 개 이동 (c,d 경유)
a -> c 로 n-k-1개 이동 (d 경유)
a -> d 로 1개 이동
c -> d 로 n-k-1개 이동 (a 경유)
b -> d 로 k 개 이동 (a,c 경유)
위와 같은 방법으로 했던것 같네요 ..
근데 k를 정하는 방법이 문제가 되죠 ..
( 뭐 어떻게 정해도 기둥 3개일때보다는 적게 옮기게 될겁니다 .. )
이런 경우엔, n값에 대한 가장 효율적인 k값이 존재합니다 ..
k = f(n) 이 되는 셈이죠 ..
이건 계산해서 얻었던 것 같은데 .. -_-;
어쨌거나 찾아보시는게 좋을것 같네요 ..
지금 찾아볼 여유가 없어서 ..
리커전은 설계만 잘 하시면 코딩은 쉬우니까 ..
잘 해내시길 바랍니다 .. 그럼 .. ;;
..;
아 ..;;
못짜겠습니다.......
힘들군요 .. 좀더 가르쳐 주실분 없나여? --a
일단 원판이 넉 장만 있다고 생각하고 손으로 풀어보세요. 그리고 그걸 일
일단 원판이 넉 장만 있다고 생각하고 손으로 풀어보세요. 그리고 그걸 일반화한 식을 세우는거죠.
그리고 이런 문제는 자신의 힘으로 풀 지 않으면 의미가 없습니다. (숙제라면 자신의 힘으로, 공부라면 끈기있게...)
하노이
리커전은 그냥 단순하게 생각하시면 됩니다
그리고 하노이 변종은 잘 모르겠구요.
굳이 2,3번 기둥을 안 거쳐도 된다면 가장 단순한 하노이의 경우를 가정하면 될 거 같습니다.
그럼 기둥이 3개가 있는 것이고
1번 기둥에 있는 n 개의 디스크를 3번 기둥으로 옮긴다면
간단히 이렇게 생각할 수 있습니다. (프로세스를 나누는 거죠)
먼저 n-1 개의 디스크를 (3번 기둥을 경유하여) 2번 기둥으로 옮기고...
나면 1번 기둥에는 디스크가 한개 남습니다.
이걸 3번으로 옮기면 됩니다.
그럼 2개의 프로세스로 구분이 되죠?
첫번째는 n-1개를 1번 기둥에서 2번 기둥으로 옮기는 프로세스와
1개의 디스크를 3번 기둥으로 옮기는 프로세스 이 2개 입니다.
n-1개를 옮기는 것은 결국 n개의 디스크를 옮기는 것과 논리적으로 같으니까
이것을 hanoi 라고 명명하고
1개를 다른 기둥으로 옮기는 것은 단순히 move라고 명명하면..
다음과 같이 됩니다.
hanoi(n, src, dest)
{
hanoi(n - 1, src, mid);
move(src, dest);
}
근데 이렇게 되면 중단점이 없기 때문에 언제까지고 계속 리커젼이 이루어집니다.
어느 시점에 끝나는 지 조건을 설정해 주면 되죠.
이 경우에 그 시점은 디스크가 1개인 경우에 그냥 move만 해주면 되므로
위 펑션을 아래와 같이 수정할 수 있습니다.
hanoi(n, src, dest, mid)
{
if (n <= 1) {
move(src, dest);
}
else {
hanoi(n - 1, src, mid, dest);
move(src, dest);
}
}
그럼..
짰습니다
도움 ㄳ,,,
근데 이글을 다짠다음에 봤습니다....^^;
암튼 감사 :lol:
댓글 달기