uva10017

题目简介:类似于汉诺塔,要求输入测试数据,每组测试包含两个整数n,m。(n表示汉诺塔中的盘子数)要求输出前m次变换是的三个柱子上的盘子的标号。(标号为盘子按照从小到大的顺序排列后的盘子的序号)程序以输入0,0结束。

我的想法:这个题目最难的地方并不是递归本身,而是控制递归结束的位置。刚开始我也失败了很多次,研究了很久才发现每个递归调用都要判断是否需要结束整个这次的计算。而且递归是有对数组的(引用)处理,这也是很值得注意的地方。

需要说明的是,这个代码中的hanoi类体里主要的输出函数名为print,另外我们用的是一个对象多次使用,所以每次用完之后要初始化以便下次再用(即在输出函数的最后加上构造函数的内容)。

样例输出与输入:2011061021575919.png

ContractedBlock.gif ExpandedBlockStart.gif View Code
 
   
1 #include < iostream >
2   using namespace std;
3 typedef int row[ 251 ];
4 class hanoi
5 {
6 private :
7 int n;
8 int m;
9 int number;
10 int array[ 3 ][ 251 ];
11 int length[ 3 ];
12 public :
13 hanoi( int a = 1 , int b = 1 )
14 {
15 n = a;
16 m = b; }
17 int input()
18 {
19 cin >> n >> m;
20 if (n == 0 && m == 0 )
21 return 0 ;
22 memset(array, 0 , sizeof (array));
23 memset(array + 1 , 0 , sizeof (array + 1 ));
24 memset(array + 2 , 0 , sizeof (array + 2 ));
25 for ( int i = n;i > 0 ;i -- )
26 array[ 0 ][n - i] = i;
27 memset(length, 0 , sizeof (length));
28 length[ 0 ] = n;
29 length[ 1 ] = 0 ;
30 length[ 2 ] = 0 ;
31 number = 1 ;
32 return 1 ;
33 }
34 void array_output(row & a)
35 { int * p = a;
36 if ( * p)
37 cout <<* p;
38 p ++ ;
39 while ( * p)
40 {
41 cout << " " <<* p;
42 p ++ ; }
43 cout << endl;
44 }
45 void move(row & a,row & b, int & numa, int & numb)
46 {
47 b[numb ++ ] = a[ -- numa];
48 a[numa] = 0 ;
49 }
50 void output()
51 {
52 cout << " A=> " ;
53 array_output(array[ 0 ]);
54 cout << " B=> " ;
55 array_output(array[ 1 ]);
56 cout << " C=> " ;
57 array_output(array[ 2 ]);
58 cout << endl;
59 }
60 int cacus( int k, int & start, int & index, int & alternate)
61 {
62 if (number > m)
63 return 0 ;
64 else {
65 if (k == 1 )
66 { move(array[start],array[index],length[start],length[index]);
67 output();
68 number ++ ;
69 return 1 ; }
70 else
71 {
72 int temp = cacus(k - 1 ,start,alternate,index);
73 if (temp == 0 )
74 return 0 ;
75 if (number > m)
76 return 1 ;
77 move(array[start],array[index],length[start],length[index]);
78 output();
79 number ++ ;
80 if (temp == 0 )
81 return 0 ;
82 temp = cacus(k - 1 ,alternate,index,start);
83 if (temp == 0 )
84 return 0 ;
85 }
86 return 1 ; }
87 }
88 void print()
89 {
90 int start = 0 ,index = 2 ,alternate = 1 ;
91 output();
92 cacus(n,start,index,alternate);
93 }
94
95 };
96 int main()
97 {
98 hanoi test;
99 int count = 0 ;
100 while (test.input())
101 {
102 count ++ ;
103 cout << " Problem # " << count << endl << endl;
104 test.print();
105 }
106 return 0 ;
107 }

我的代码:

转载于:https://www.cnblogs.com/zhwyprime/archive/2011/06/10/2077988.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值