Problem Description
还记得汉诺塔III吗?他的规则是这样的:不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到小盘的上面。xhd在想如果我们允许最大的盘子放到最上面会怎么样呢?(只允许最大的放在最上面)当然最后需要的结果是盘子从小到大排在最右边。
Input
输入数据的第一行是一个数据T,表示有T组数据。
每组数据有一个正整数n(1 <= n <= 20),表示有n个盘子。
Output
对于每组输入数据,最少需要的摆放次数。
Sample Input
2
1
10
Sample Output
2
19684
分析:
分解为三个子问题。当n = num即输入个数时,…写思路好麻烦噢嘤嘤嘤,之后再补吧
代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define maxn 60
long long int i =0;
int num;
void move(int n, char from, char to)
{
if (abs(from - to ) != 1)
{
i+=2;
}
else
i++;
}
void hanoi(int n, char from , char depend, char to)
{
if (n == 1)
move(n, from, to);
else if(n == num)
{
long long int n1;
hanoi(n-1,from, to, depend);
n1 = i;
i = n1*2 + 2;
}
else
{ long long int n2;
if (abs(from - to ) == 1)
{
hanoi(n-1,from, to, depend);
hanoi(n-1,depend,from,to);
i++;
}
else
{
long long int n3, n4, n5;
n3 = i;
hanoi(n-1, from, depend, to);
//hanoi(n-1,to,depend,from);
//hanoi(n-1,from,depend,to);
n4 = i-n3;
i+=2*n4 +2;
}
}
}
int main()
{
int n;
char x='A', y='B', z='C';
scanf("%d", &n);
while(n--)
{ scanf("%d", &num);
i=0;
hanoi(num, x,y,z);
printf("%lld\n", i);
}
return 0;
}
注意:一定hanoi()前用n3存当前i,再用hanoi()函数执行后的i减去n3才是执行一次当前步骤所需要的步数,而不能直接去i*3+2 !!!