前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >算法训练 Hanoi问题

算法训练 Hanoi问题

作者头像
刘开心_1266679
发布2019-02-14 15:36:34
8110
发布2019-02-14 15:36:34
举报

问题描述

  如果将课本上的Hanoi塔问题稍做修改:仍然是给定N只盘子,3根柱子,但是允许每次最多移动相邻的M只盘子(当然移动盘子的数目也可以小于M),最少需要多少次?   例如N=5,M=2时,可以分别将最小的2个盘子、中间的2个盘子以及最大的一个盘子分别看作一个整体,这样可以转变为N=3,M=1的情况,共需要移动7次。

输入格式

  输入数据仅有一行,包括两个数N和M(0<=M<=N<=8)

输出格式

  仅输出一个数,表示需要移动的最少次数

样例输入

5 2

样例输出

7 思路:        解题需要两步:1、转换成传统Hanoi问题    2、输出转换后的步数。        1、此Hanoi塔与传统Hanoi塔的关系为:把n个盘中的每m个想成一个整体,就变成了传统的只能一次移动一个盘的Hanoi问题,n / m (如果有余数则+1)的结果就成了传统Hanoi塔的盘子数;        2、分析传统Hanoi塔,假设初始状态盘子都在柱子A上,B为目标柱子,C为临时柱子,移动两个盘,需要3步(小盘--->C,大盘--->B,小盘---->B),移动三个盘,需要把前两个盘移动到柱子C,再将最大盘移到目标柱子,再把前两个盘移动到目标柱子,所以需要的步数为3(移两个盘)+ 1(移动最大盘) + 3(移两个盘) = 7步,移动四个盘,需要把前三个盘移动到柱子C,再把最大盘移动到目标柱子,再把前三个盘子移动到目标柱子,所以需要的步数为7 + 1 + 7 = 15步,依此类推。

代码语言:javascript
复制
#include <cstdio>

int Conver(int n, int m)
{
	if(n % m != 0)
		return n / m + 1;	
	else
		return n / m;
} 

int Hanoi(int n)
{
	if(n == 2)
		return 3;
	else
		return 2 * Hanoi(n - 1) + 1;
}

int main()
{
	int n, m, con, ans;
	scanf("%d%d", &n, &m);
	con = Conver(n, m);
	ans = Hanoi(con);
	printf("%d\n", ans);
	return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015年03月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档