题目描述
汉诺塔是一个经典问题,相传在古印度圣庙中,有一种被称为汉诺塔(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;
}
来源:CSDN
作者:correct!
链接:https://blog.csdn.net/weixin_43701790/article/details/104226630