swustoj 143 汉诺塔问题

Description

(n阶Hanoi塔问题)假设有三个分别命名为A、B、C的塔座,在塔座A上插有n(n<20)个直径大小各不相同、依小到大编号为1,2,…,n的圆盘。现要求将A轴上的n个圆盘移至塔座C上并仍按同样顺序叠排,圆盘移动时必须遵循下列规则: 1)每次只能移动一个圆盘; 2)圆盘可以插在A、B、C中的任一塔座上; 3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。 请通过编程来打印出移动的步骤.

Input

只有一组输入数据.输入数据N(;表示在开始时A塔座上的盘子数),当输入0时程序结束.

Output

输出移动的步骤.如"A-->C","A-->B"等.每两的步骤之间有三个空格隔开,每输出5个步骤就换行.详细的见Sample Output.

Sample Input

5

2

0

 

Sample Output

A--&gt;C A--&gt;B C--&gt;B A--&gt;C B--&gt;A

B--&gt;C A--&gt;C A--&gt;B C--&gt;B C--&gt;A

B--&gt;A C--&gt;B A--&gt;C A--&gt;B C--&gt;B

A--&gt;C B--&gt;A B--&gt;C A--&gt;C B--&gt;A

C--&gt;B C--&gt;A B--&gt;A B--&gt;C A--&gt;C

A--&gt;B C--&gt;B A--&gt;C B--&gt;A B--&gt;C

A--&gt;C

A--&gt;B A--&gt;C B--&gt;C 

 

Hint

注意:此题每一行最后有3个空格

 

首先说一下,题目上的输出乱了,我直接复制的没有改,&gt应该是>

 

汉诺塔问题是个很经典的递归问题,但也比较难理解。

 

解题的方法大致是:移动当前n阶汉诺塔的最大一个盘子到目的柱子叠起来,将n阶汉诺塔变成n-1级汉诺塔,然后重复挪n-1个中最大的盘子到目的柱子,直到挪成一阶汉诺塔

先写一下核心的解法

void move(int n,char x,char y,char z)

{
if (n == 1)
{
printf("%c-->%c   ", x, z);
return;
}
move(n-1,x,z,y);
printf("%c-->%c   ",x, z);
move(n-1,y,x,z);
}

下面是ac代码及详解:

 

#include<stdio.h>
int vis;//这个参数和算法无关,只是为了标记,满足题目的五步一换行,否则题目会PE
int main()
{
	int n;
	void move(int n, char x, char y, char z);//******此函数的作用是将x柱子上的n个盘子移动到z柱子上,同时输出要经历的步骤

	while (~scanf("%d",&n) && n)
	{
		vis=1;
		move(n, 'A', 'B', 'C');//函数的直接目的,将A柱上的盘子移到C柱,同时输出步骤
		if ((--vis % 5))printf("\n");//如果最后一位刚好是第五个
	}
	return 0;
}

void move(int n,char x,char y,char z)//x为初始塔,y表示借助塔,z表示目标塔。
{
//******此函数的作用是将x柱子上的n个盘子移动到z柱子上,同时输出要经历的步骤,x上面的盘子始终是由小到大
//x表示当前要移动的盘子所在的柱子,n表示当前有多少个盘子在x上,y表示借助y柱子,z表示需要把x上的n个盘子移动到z柱子上。
	

	if (n == 1)//n=1时,x上只剩一个盘子的时候,直接移动到z
	{
		printf("%c-->%c   ", x, z);
		if (!(vis++ % 5))printf("\n");
		return;
	}
	//n>1时,x上还有n个盘子的时候,当前目的就是把上面的n-1个盘子全挪到y上,这样就可以把当前最大的那个盘子挪到z上
	//怎么挪呢?

	move(n-1,x,z,y);//首先请看上面注了六个*号的那句话。
	//不管这步的函数内部是怎么运行的,总之,这个函数的运行后的效果是将x柱子上的n-1个盘子移动到y柱子上

	printf("%c-->%c   ",x, z);//移动x上的盘子到z上,ps:虽然没有挪动这个操作,但挪动到目标位置后就不用管了,变成了n-1阶汉诺塔,所以直接无视掉它
	if (!(vis++ % 5))printf("\n");//五个一换行
	//关键是要知道每步的作用是什么,不用去想它是怎么做到的
	//现在我们的目的就变成了将y上的n-1个盘子移动到z上
	move(n-1,y,x,z);//接下来我们只需要解决n-1阶汉诺塔了,也就是这个函数的目的,将y上剩余的n-1个盘子移动到z柱子上
}


成在坚持,贵在坚持,难在坚持!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章