牛牛的汉诺塔

题目链接

题目描述

汉诺塔是一个经典问题,相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置n个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

牛牛很快就理解了代码的意思并且写出了求解汉诺塔的程序,他现在想研究汉诺塔的规律。       请你统计以下信息:A->B,A->C,B->A,B->C,C->A,C->B的次数,以及所有移动的总步数。

思路

总步数好算,是2^{n} - 1,然后就是打表大法 ,怪我太菜

打表后,找规律,如果把上述的信息以一个数组f[1]~f[6]存放的话,可以发现

n为奇数:

f[i][1] = f[i - 1][1];
f[i][4] = f[i - 1][4];
f[i][5] = f[i - 1][5];
f[i][6] = f[i - 1][5] * 2 + i / 2;
f[i][2] = f[i][6] + (i + 1) / 2;
f[i][3] = f[i][6];

n为偶数:

f[i][2] = f[i - 1][2];
f[i][3] = f[i - 1][3];
f[i][6] = f[i - 1][6];
f[i][5] = f[i - 1][6] * 2;
f[i][1] = f[i][4] = f[i][5] + i / 2;

 按照规律,循环一遍就行了

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 66;
typedef long long ll;
ll f[N][10];
int main()
{
	f[1][1] = 0;
	f[1][2] = 1;
	f[1][3] = 0;
	f[1][4] = 0;
	f[1][5] = 0;
	f[1][6] = 0;
	f[2][1] = 1;
	f[2][2] = 1;
	f[2][3] = 0;
	f[2][4] = 1;
	f[2][5] = 0;
	f[2][6] = 0;
	f[1][7] = 1;
	f[2][7] = 3;
	int n;
	scanf("%d", &n);
	ll sum = 8;
	for (int i = 3; i <= n; i++){
		if(i & 1){
			f[i][1] = f[i - 1][1];
			f[i][4] = f[i - 1][4];
			f[i][5] = f[i - 1][5];
			f[i][6] = f[i - 1][5] * 2 + i / 2;
			f[i][2] = f[i][6] + (i + 1) / 2;
			f[i][3] = f[i][6];
		}
		else{
			f[i][2] = f[i - 1][2];
			f[i][3] = f[i - 1][3];
			f[i][6] = f[i - 1][6];
			f[i][5] = f[i - 1][6] * 2;
			f[i][1] = f[i][4] = f[i][5] + i / 2;
		}
		f[i][7] = sum - 1;
		sum <<= 1;
	}
	printf("A->B:%lld\n", f[n][1]);
	printf("A->C:%lld\n", f[n][2]);
	printf("B->A:%lld\n", f[n][3]);
	printf("B->C:%lld\n", f[n][4]);
	printf("C->A:%lld\n", f[n][5]);
	printf("C->B:%lld\n", f[n][6]);
	printf("SUM:%lld", f[n][7]);
	return 0;
}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值