4147:汉诺塔问题,考点:递归、栈实现递归

原题:http://bailian.openjudge.cn/practice/4147/

描述

一、汉诺塔问题

  有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆: 每次只能移动一个圆盘; 大盘不能叠在小盘上面。 提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。

  问:如何移?最少要移动多少次?

输入

输入为一个整数后面跟三个单字符字符串。
整数为盘子的数目,后三个字符表示三个杆子的编号。

输出

输出每一步移动盘子的记录。一次移动一行。
每次移动的记录为例如3:a->b 的形式,即把编号为3的盘子从a杆移至b杆。
我们约定圆盘从小到大编号为1, 2, ...n。即最上面那个最小的圆盘编号为1,最下面最大的圆盘编号为n。

样例输入

3 a b c

样例输出

1:a->c
2:a->b
1:c->b
3:a->c
1:b->a
2:b->c
1:a->c

解法

思路一:直接递归,这是递归入门经典题了

 1 #include <iostream>
 2 using namespace std;
 3 void move(int n, char nows, char uses, char targets,int pan) {
 4     if (n == 1) {
 5         cout << pan << ":" << nows << "->" << targets << endl;
 6         return;
 7     }
 8     move(n - 1, nows, targets, uses, pan - 1);
 9     move(1, nows, uses, targets, pan);
10     move(n - 1, uses, nows, targets, pan - 1);
11     return;
12 }
13 int main()
14 {
15     int n;
16     char a, b, c;
17     cin >> n >> a >> b >> c;
18     move(n, a, b, c, n);
19     return 0;
20 }
21 */

思路二:用栈实现递归,注意入栈的顺序

 1 #include <iostream>
 2 #include <stack>
 3 using namespace std;
 4 class Move {
 5 public:
 6     int n;
 7     char nows, uses, targets;
 8     int pan;//目前最大的盘子编号
 9     Move(int inn,char innows,char inuses,char intargets,int inpan):n(inn),nows(innows),uses(inuses),targets(intargets),pan(inpan){}
10 };
11 stack<Move>mystack;
12 int main()
13 {
14     int n;
15     char a, b, c;
16     cin >> n >> a >> b >> c;
17     mystack.push(Move(n, a, b, c, n));
18     while (!mystack.empty()) {
19         Move topn = mystack.top();
20         mystack.pop();
21         if (topn.n == 1) {
22             cout << topn.pan << ":" << topn.nows << "->" << topn.targets << endl;
23             continue;
24         }
25         //注意放入栈的顺序和上面的递归是倒过来的
26         mystack.push(Move(topn.n - 1, topn.uses, topn.nows, topn.targets, topn.pan - 1));
27         mystack.push(Move(1, topn.nows, topn.uses, topn.targets, topn.pan));
28         mystack.push(Move(topn.n - 1, topn.nows, topn.targets, topn.uses, topn.pan - 1));
29     }
30     return 0;
31 }

 

posted @ 2021-07-09 11:47  永远是个小孩子  阅读(121)  评论(0编辑  收藏  举报