玩游戏写算法——汉诺塔

玩了个汉诺塔的flash游戏,总结下算法

四五层就不说了,太长,4层要15步,每步一截屏就刷死了,其实要想归纳出规律,最好还是玩四五层看看,多了才出规律。


上小下大,一个压一个,想把最底下的第 n 个盘子移到目的地 C ,必须把其余的 n-1 个移到中转柱 B
那第 n-1 个盘子必须在中转柱 B 的最底下,也就是问题转换成把上边这n-1个盘子的“最底下”的(第n-1个)盘子移到目的柱B,
此时第 n-1 个盘子上边的 n-2 个盘子在 C




以三层为例,八张图,七步,步骤如下:












游戏过程归纳成算法:步骤拆解,注意我说的第N-几个盘子是从上边数的,和此游戏标的数字相反

注意:每一个中转柱到下一层递归就成为了目的柱,就是传形参嘛,每堆从上边数的(n-i)个盘子都有不同的目的,为了方便,把字母A源、B中转、C目的还是代入了

单层结构示意

hanoi(N,A,B,C){

hanoi(上边N-1盘子个从源A到中转B;

第N个盘子直接源A到目的C;

hanoi(上边N-1个盘子从中转B到目的C;

}

伪代码函数原型(文字叙述的N个盘子从AC即为hanoi(N,A,B,C)

hanoi(N,A,B,C){

hanoiN-1,A,C,B;

第N个盘子直接源A到目的C;

hanoiN-1,B,A,C;

}

 


为了描述清晰,还是用文字展开过程吧

首次调用——参数N——hanoi(N,A,B,C);

hanoi(上边N-1盘子个从源A中转B;

第N个盘子直接源A到目的C;

hanoi(上边N-1个盘子从中转B目的C;

全层次完全展开:

hanoi(上边N-1盘子个从源A中转B;

第N个盘子直接源A到目的C;

hanoi(上边N-1个盘子从中转B目的C;

参数N-1——hanoi(N-1,A,B,C);

hanoi(上边N-2盘子个从源A中转B;

第N-1个盘子直接源A到目的C;

hanoi(上边N-2个盘子从中转B目的C;

全层次完全展开(新的一层,形参,中转B已变成目的B

hanoi(上边N-2盘子个从源A中转C),第N-1个盘子直接源A目的Bhanoi(上边N-2个盘子从中转C到目的B));

第N个盘子直接源A到目的C;

hanoi上边N-2个盘子从B中转A),第N-1个盘子直接从B目的Chanoi(上边N-2个盘子从中转A到目的C;



(左边一个递归展开,中间一个操作,右边一个递归展开,两边展开中间不动,挺像二叉树的操作)

.....

......

以此类推,参数为2

hanoi(上边1盘子个从源A中转B;

2个盘子直接源A到目的C;

hanoi(上边1个盘子从中转B目的C;

完全展开,已经展不开了,太大了

 

直到参数为1——hanoi(1,A,B,C);

这时候该结束了,if(N==1),直接AC(想想一层汉诺塔),其他的都不管了

 

 

所以hanoi函数为

void move(char getone,char putone)

{     cout<< getone <<"-->"<<putone<<endl; }

void hanoi(int n,char one,char two,char three)

{       void move(char getone,char putone);

        if (n==1) move (one,three);

        else

        {   hanoi (n-1,one,three,two);

            move(one,three);

            hanoi(n-1,two,one,three);

        }

}



程序运行结果:匹配,三层七步,四层十五步








  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
汉诺塔问题是一个经典的问题,源于印度一个古老传说。问题是将一根柱子上的64片黄金圆盘按照大小顺序重新摆放到另一根柱子上,且在任何时候,小圆盘上不能放大圆盘,且一次只能移动一个圆盘。 汉诺塔问题的循环算法可以使用迭代的方式来解决。下面是一个示例代码: ```cpp #include <iostream> #include <stack> #include <string> using namespace std; void hanoiTowerIterative(int N, string from, string to, string help) { stack<int> s1, s2, s3; int moves = (1 << N) - 1; for (int i = N; i > 0; i--) { s1.push(i); } if (N % 2 == 0) { swap(s2, s3); } for (int i = 1; i <= moves; i++) { if (i % 3 == 1) { if (s1.empty() || (!s2.empty() && s2.top() < s1.top())) { cout << "Move " << s2.top() << " from " << to << " to " << from << endl; s1.push(s2.top()); s2.pop(); } else { cout << "Move " << s1.top() << " from " << from << " to " << to << endl; s2.push(s1.top()); s1.pop(); } } else if (i % 3 == 2) { if (s1.empty() || (!s3.empty() && s3.top() < s1.top())) { cout << "Move " << s3.top() << " from " << help << " to " << from << endl; s1.push(s3.top()); s3.pop(); } else { cout << "Move " << s1.top() << " from " << from << " to " << help << endl; s3.push(s1.top()); s1.pop(); } } else { if (s2.empty() || (!s3.empty() && s3.top() < s2.top())) { cout << "Move " << s3.top() << " from " << help << " to " << to << endl; s2.push(s3.top()); s3.pop(); } else { cout << "Move " << s2.top() << " from " << to << " to " << help << endl; s3.push(s2.top()); s2.pop(); } } } } int main() { hanoiTowerIterative(3, "A", "B", "C"); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值