题目描述:n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列。由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从下往上的大小仍保持如下关系 :
n=m+p+q
a1>a2>...>am
b1>b2>...>bp
c1>c2>...>cq
ai是A柱上的盘的盘号系列,bi是B柱上的盘的盘号系列, ci是C柱上的盘的盘号系列,最初目标是将A柱上的n个盘子移到C盘. 给出1个系列,判断它是否是在正确的移动中产生的系列.
例1:n=3
3
2
1
是正确的
例2:n=3
3
1
2
是不正确的。
注:对于例2如果目标是将A柱上的n个盘子移到B盘. 则是正确的.


解题方法:这道题想了很久,自己并没有很好的方法,最后看了别人的题解,下面是根据别人题解来描述这道题目的解法
                 记左边的柱子为A,中间的为B,右边的为C。
              1)有n个盘子汉诺塔的最少的移动步数是2^n-1;
              2)最大的盘子一定不可能出现在中间的柱子上(反之,出现则一定错误)
              3)当所有的盘子在左边或者在右边这个序列一定合法。
              4)最大的盘子不在中间的柱子上,而初始值最大盘子是在左边的柱子上,则必有:
                   1、最大的盘子在左边:最大的盘子在左边,由于盘子是从小到大,则意味着要将最大盘子上面的所有盘子移到中间的柱子上。
                                                 那么所需要的操作是:A->B  移动N-1个盘子,A->C移动最大的盘子。
                                                 可以明显的看见A->B移动N-1盘子是移动最大的盘子的先决条件,也就是前状态。
                                                 而这个前状态可以视为有由A->C移动N-2个盘子,再A->B移动N-1中最大的盘子,再将N-2个盘子做操作C->A;
                                                 这样子,一个递推规律就产生了。
                                                 只要在开始A->C移动最大盘子的时候虚拟的交换B跟C的位置就可以视下一步操作依旧是A->C移动最大的盘子。                            
                   2、最大的盘子在右边:最大的盘子在右边,则N-1个盘子一定在中间的柱子上,那么根据上边的规律我们只要在每一次移动的时候交换A,B的位置就可以了



关于汉诺塔问题非递归做法,里面有个lg(m)就操作...
http://placespecial.wordpress.com/2007/10/29/%E6%B1%89%E8%AF%BA%E5%A1%94%E7%9A%84%E4%B8%A4%E7%A7%8D%E9%9D%9E%E9%80%92%E5%BD%92%E8%A7%A3%E6%B3%95%EF%BC%88%E8%BD%AC%EF%BC%89/


这是根据别人思路写的一个代码,感触良多。
 1#include <iostream>
 2#include <cstdio>
 3#include <cmath>
 4#include <cstring>
 5
 6using namespace std;
 7
 8int maxx[4],n[4],h[4][65];
 9int a,b,c,i,N,T,temp;
10
11bool working()
12{  while(1)
13     {  if(n[c]==N||n[a]==N)
14          {return truebreak;}
15        if(n[b]>0&&h[b][maxx[b]]==N)
16          {return falsebreak;}
17        if(n[a]>0&&h[a][maxx[a]]==N)
18          { N--; n[a]--; maxx[a]++;
19            temp=b;b=c;c=temp;
20            continue;
21          }

22        if(h[c][maxx[c]]==N&&n[c]>0)
23          { N--; n[c]--; maxx[c]++;
24            temp=b;b=a;a=temp;
25            continue;
26          }

27      }

28}

29
30
31int main()
32{
33  scanf("%d",&T);
34  while(T--)
35  {  a=1;b=2;c=3;
36     maxx[a]=1;
37     maxx[b]=1;
38     maxx[c]=1;
39     scanf("%d",&N);
40     scanf("%d",&n[a]);
41     for(i=1;i<=n[a];i++)
42       scanf("%d",&h[a][i]);
43     scanf("%d",&n[b]);
44     for(i=1;i<=n[b];i++)
45       scanf("%d",&h[b][i]);
46     scanf("%d",&n[c]);
47     for(i=1;i<=n[c];i++)
48       scanf("%d",&h[c][i]);
49     if(working()) printf("true\n");
50        else printf("false\n");
51  }

52  return 0;
53}

54