https://ac.nowcoder.com/acm/problem/14585

题意:只能通过移动到相邻位置的汉诺塔问题。

汉诺塔讲解:有三根A,B,C相邻的柱子,A柱子从上到下按递增方式摆放了n个不同大小的圆盘,现在要把A中所有的盘子移动到柱子C上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方,盘子只能移动到相邻的柱子上。(比传统汉诺塔多了最后一个限定条件)
具体移动实现方式还是一样用递归的思想:

1:当只有一个圆盘时,移动方式为:A->B,B->C
2:当只有两个圆盘时,移动方式为:把最上面的盘子1移动到B,再把盘子1移动到C。把下面的盘子2移动到B,然后把盘子1移动回到B,再移动回到A,此时就可把2移动到C,最后把盘子1由A移动到B,再由B移动到A即可完成。敲黑板(自己手动模拟一下)
3:......

总结:

1:当只有一个盘子时,由A->B->C。
2:当有n个盘子时,要把1--n-1圆盘从左边移动到右边,再将最下面的圆盘n移动到中间,
把1——n-1圆盘从右边移动到左边,把圆盘n从中间移动到右边,1——n-1圆盘从左边移动到右边。

代码:

void move(char a, char b, char c, int n){
    if(n == 0){//递归出口
        return;
    }
    move(a,b,c,n-1);                    //把前n - 1块通过b移动到c上
    ans++;                                    //把最后一块移动到b上
    //printf("%c->%c\n",a,b);
    move(c, b , a, n - 1);                  //把n - 1 块通过b移动到a上
    ans++;                                   //中间那块移动到c,成功一块
    //printf("%c->%c\n",b,c);
    move(a,b,c,n-1);                   //继续以上操作
}

当然,虽然n只有26,但这样交个递归函数上去,无疑会超时,那怎么办呢?我们不妨打个表来看看,观察一下n和ans之间有什么关系吧。

n取1~10:
1:2 2:8 3:26 4:80 5:242 6:728 7:2186 8:6560 9:19682 10:59048

不难发现:ans=3^n-1

那么问题ac代码就简单了:

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
ll i,j,cnt,n,k,t;
ll ans;
int main()
{
    while(~scanf("%lld",&n)){
        ans=pow(3,n)-1;
        printf("%lld\n",ans);
    }
}