链接:https://ac.nowcoder.com/acm/contest/3004/I
汉诺塔是一个经典问题,相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置n个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
汉诺塔以及其衍生问题往往使用递归来求解,也是学习和理解递归很好的老师。
其伪代码如下
Function Hanoi(n,a,b,c) if n==1 then print(a+'->'+c) else Hanoi(n-1,a,c,b) print(a+'->'+c) Hanoi(n-1,b,a,c) end if end Function
牛牛很快就理解了代码的意思并且写出了求解汉诺塔的程序,他现在想研究汉诺塔的规律。
请你统计以下信息:A->B,A->C,B->A,B->C,C->A,C->B的次数,以及所有移动的总步数。
输入描述:
仅一行,输入一个正整数n(1 \leq n \leq 60)(1≤n≤60)表示汉诺塔的层数。
输出描述:
首先输出6行
A->B:XX
A->C:XX
B->A:XX
B->C:XX
C->A:XX
C->B:XX
分别表示每种移动情况出现的次数
最后输出一行
SUM:XX
表示所有移动情况的总和。
示例1
输入
复制
3
输出
复制
A->B:1 A->C:3 B->A:1 B->C:1 C->A:0 C->B:1 SUM:7
说明
伪代码所示算法的移动序列如下:
A->C
A->B
C->B
A->C
B->A
B->C
A->C
统计:
A->B出现1次
A->C出现3次
B->C出现1次
B->A出现1次
C->B出现1次
总计7次
代码:
#include<bits/stdc++.h>
using namespace std;
long long n,m,t,g,l,s1=0,s2=0,s3=0,s4=0,s5=0,s6=0,w,o,r,ans,s=0,max1=0,min1=0;
long long ppow(long long a, long long b)
{
long long ans = 1;
while(b > 0){
if(b & 1){
ans = ans * a ;
}
a = a * a ;
b >>= 1;
}
return ans;
}
int main()
{
cin>>n;
s=ppow(2,n)-1;
g=1;
if(n==1)
s2=1;
for(int i=2,k=1;i<=n+2;i++)
{
if(i%2==1)
{
g=g*4-k;
k+=2;
}
if(i==n)
s2=g;
if(i==n+1)
{
s1=(g-1)/2;
s4=s1;
}
}
if(n<=2)
{
s3=0;
s5=0;
s6=0;
}
else if(n==3)
{
s3=1;
s6=1;
}
else if(n==4)
{
s3=1;
s6=1;
s5=2;
}
else
{
g=1;
for(int i=5,k=2;i<=n+2;i++)
{
if(i%2==1)
{
g=g*4+k;
k++;
}
if(i==n)
{
s3=g;
s6=g;
}
if(i==n-1)
{
s5=g*2;
}
}
if(n==5)
s5=2;
}
cout<<"A->B:"<<s1<<endl;
cout<<"A->C:"<<s2<<endl;
cout<<"B->A:"<<s3<<endl;
cout<<"B->C:"<<s4<<endl;
cout<<"C->A:"<<s5<<endl;
cout<<"C->B:"<<s6<<endl;
cout<<"SUM:"<<s<<endl;
}