牛牛的汉诺塔

本小妞迷上赌 提交于 2020-02-08 19:19:00

题目链接

题目描述

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

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

思路

总步数好算,是

,然后就是打表大法 ,怪我太菜

打表后,找规律,如果把上述的信息以一个数组

~

存放的话,可以发现

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;
}

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!