Live2D

汉诺塔(河内之塔)相关题目

1. 标准汉诺塔

题目:

汉诺塔由三根柱子(分别用A、B、C表示)和n个大小互不相同的空心盘子组成。一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体。 对汉诺塔的一次合法的操作是指:从一根柱子的最上层拿一个盘子放到另一根柱子的最上层,同时要保证被移动的盘子一定放在比它更大的盘子上面(如果移动到空柱子上就不需要满足这个要求)。

分析:

首先把n个盘子分成两部分 底层的一个大盘子和其他的盘子,其他的盘子
其他盘子从A移到B =>hanoi(n-1,a,c,b)
底层盘子从A移到C =>move(a,c)
其他盘子从B移到C => hanoi(n-1,b,a,c);

代码:

#include <iostream>
using namespace std;

void move(char a,char c){
cout<<a<<" move to "<<c<<endl;
}
void hanoi(int n,char a,char b,char c){
	if(n==1){
		move(a,c);
	}else{
		hanoi(n-1,a,c,b);
		move(a,c);
		hanoi(n-1,b,a,c);
	}
}
int main(){
    hanoi(3,'A','B','C');
	return 0;
}

2. P1760 通天之汉诺塔

题目:

在你的帮助下,小A成功收集到了宝贵的数据,他终于来到了传说中连接通天路的通天山。但是这距离通天路仍然有一段距离,但是小A突然发现他没有地图!!!但是幸运的是,他在山脚下发现了一个宝箱。根据经验判断(小A有经验吗?),地图应该就在其中!在宝箱上,有三根柱子以及在一根柱子上的n个圆盘。小A在经过很长时间判断后,觉得这就是hanoi塔!(这都要琢磨)。但是移动是需要时间的,所以小A必须要通过制造延寿药水来完成这项任务。现在,他请你告诉他需要多少步完成,以便他造足够的延寿药水.。时限1s。

输入格式:
一个数n,表示有n个圆盘
输出格式:
一个数s,表示需要s步。
说明:
对于所有数据n<=15000

分析:

汉诺塔 递推式为 \(H(k)= 2H(k-1)+1​\)
公式为 \(H(k) = 2^{k} - 1​\)

这道题公式很简单关键是数据范围15000,这是一个很大的数
\(2^{k}\)的位数是 \(nlg2\) , \(lg2\approx0.3\)
long long 十进制位数大约是19位 ,所以要用高精度计算

代码:

#include <iostream>
#include<cmath>
using namespace std;
void gaojingdu(int n){
	int k=5000;
	int a[k];  // k 表示位数 2^n的位数为nlg2 lg2 大约 0.3
	memset(a,0,sizeof(a));

	int s=0,w=0; // 计算中间结果  进位
	a[0] = 1;

	int q=1;   //位数
	for(int i=0;i<n;i++){
		for(int j=0;j<q;j++){
			s =  a[j] * 2 + w;
			a[j] = s %10;
			w = s/10;
		}
		if(w!=0){a[q]=w;q++;w=0;}  //最高位计算之后出现进位 位数加1 
	}

    int b = 0;    //这一块是减1
	while(a[b]==0){
	   a[b] = 9;
       b++;
	}
	a[b] = a[b] -1;


	for(int i = q-1;i>=0;i--){	
			cout<<a[i];		
	}
	cout<<endl;
}

int main(){
	int n;
	cin>>n;
	gaojingdu(n);
	return 0;
}

3. P4285 [SHOI2008]汉诺塔

题目:

汉诺塔由三根柱子(分别用A、B、C表示)和n个大小互不相同的空心盘子组成。一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体。 对汉诺塔的一次合法的操作是指:从一根柱子的最上层拿一个盘子放到另一根柱子的最上层,同时要保证被移动的盘子一定放在比它更大的盘子上面(如果移动到空柱子上就不需要满足这个要求)。我们可以用两个字母来描述一次操作:第一个字母代表起始柱子,第二个字母代表目标柱子。例如,AB就是把柱子A最上面的那个盘子移到柱子B。汉诺塔的游戏目标是将所有的盘子从柱子A移动到柱子B或柱子C上面。 有一种非常简洁而经典的策略可以帮助我们完成这个游戏。首先,在任何操作执行之前,我们以任意的次序为六种操作(AB、AC、BA、BC、CA和CB)赋予不同的优先级,然后,我们总是选择符合以下两个条件的操作来移动盘子,直到所有的盘子都从柱子A移动到另一根柱子: (1)这种操作是所有合法操作中优先级最高的; (2)这种操作所要移动的盘子不是上一次操作所移动的那个盘子。 可以证明,上述策略一定能完成汉诺塔游戏。现在你的任务就是假设给定了每种操作的优先级,计算按照上述策略操作汉诺塔移动所需要的步骤数。

输入格式:
输入有两行。第一行为一个整数n(1≤n≤30),代表盘子的个数。第二行是一串大写的ABC字符,代表六种操作的优先级,靠前的操作具有较高的优先级。每种操作都由一个空格隔开。
输出格式:
只需输出一个数,这个数表示移动的次数。我们保证答案不会超过10的18次方。
说明:
对于20%的数据,n ≤ 10。 对于100%的数据,n ≤ 30。

输入输出样例
输入样例#1:

3
AB BC CA BA CB AC

输出样例#1:

7

挖坑

4. P1242 新汉诺塔

题目:

设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号。将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A、B、C,这个状态称为初始状态。
现在要求找到一种步数最少的移动方案,使得从初始状态转变为目标状态。
移动时有如下要求:
一次只能移一个盘;
不允许把大盘移到小盘上面。

输入格式:

文件第一行是状态中圆盘总数;
第二到第四行分别是初始状态中A、B、C柱上圆盘的个数和从上到下每个圆盘的编号;
第五到第七行分别是目标状态中A、B、C柱上圆盘的个数和从上到下每个圆盘的编号。
输出格式:
每行一步移动方案,格式为:move I from P to Q
最后一行输出最少的步数。
说明:
圆盘总数≤45
每行的圆盘描述是从下到上的圆盘编号

输入输出样例

输入样例#1:

5
3 3 2 1
2 5 4
0
1 2
3 5 4 3
1 1

输出样例#1:

move 1 from A to B
move 2 from A to C
move 1 from B to C
move 3 from A to B
move 1 from C to B
move 2 from C to A
move 1 from B to C
7

挖坑

posted @ 2019-04-10 23:18  Duiliur  阅读(866)  评论(0编辑  收藏  举报