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);
}
}
京公网安备 11010502036488号