汉诺塔VII(递推,模拟)

汉诺塔VII

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1503 Accepted Submission(s): 1077
 

Problem Description

n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列。由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从下往上的大小仍保持如下关系 : 
n=m+p+q
a1>a2>...>am
b1>b2>...>bp
c1>c2>...>cq
ai是A柱上的盘的盘号系列,bi是B柱上的盘的盘号系列, ci是C柱上的盘的盘号系列,最初目标是将A柱上的n个盘子移到C盘. 给出1个系列,判断它是否是在正确的移动中产生的系列.
例1:n=3
3
2
1
是正确的
例2:n=3
3
1
2
是不正确的。
注:对于例2如果目标是将A柱上的n个盘子移到B盘. 则是正确的.


Input

包含多组数据,首先输入T,表示有T组数据.每组数据4行,第1行N是盘子的数目N<=64.
后3行如下
m a1 a2 ...am
p b1 b2 ...bp
q c1 c2 ...cq
N=m+p+q,0<=m<=N,0<=p<=N,0<=q<=N,


Output

对于每组数据,判断它是否是在正确的移动中产生的系列.正确输出true,否则false


Sample Input

6
3
1 3
1 2
1 1
3
1 3
1 1
1 2
6
3 6 5 4
1 1
2 3 2
6
3 6 5 4
2 3 2
1 1
3
1 3
1 2
1 1
20
2 20 17
2 19 18
16 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1


Sample Output

true
false
false
false
true
true

题解:借助人家的代码,方法是找第n个盘子要在A盘或者C盘;

下面是人家的思路:

①考虑最大盘子 n 号盘子,移动方向为A——>C,它只能在A或者C上,如果它在B上,则为false;

②如果 n 号盘子在 A 上,则其上的 n-1 号盘子必处于从A——>B的移动过程中,此时最大盘号为 n-1,移动方向为A—>B;

③如果 n 号盘子在 C 上,则其上的 n-1 号盘子必处于从B——>C的移动过程中,此时最大盘号为 n-1,移动方向为B—>C;

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
using namespace std;
const int INF=0x3f3f3f3f;
#define mem(x) memset(x,0,sizeof(x))
#define SI(x) scanf("%d",&x)
#define PI(x) printf("%d",x)
#define SL(x) scanf("%lld",&x)
#define P_ printf(" ")
#define T_T while(T--)
const int MAXN=70;
int a[4][MAXN];
bool work(int n,int m,int p,int q){
	//最大的盘子一定在A盘或者c盘上;
	if(n==0)return true;
	//PI(n);
	if(a[m][a[m][0]]==n){
		a[m][0]--;
		return work(n-1,m,q,p);
	}
	if(a[q][a[q][0]]==n){
		a[q][0]--;
		return work(n-1,p,m,q);
	}
	return false;
}
int main(){
	int n,m,p,q,T;
	SI(T);
	T_T{
		SI(n);
		SI(a[1][0]);
		for(int i=a[1][0];i>=1;i--)SI(a[1][i]);
		SI(a[2][0]);
		for(int i=a[2][0];i>=1;i--)SI(a[2][i]);
		SI(a[3][0]);
		for(int i=a[3][0];i>=1;i--)SI(a[3][i]);
		if(work(n,1,2,3))puts("true");
		else puts("false");
	}
	return 0;
}

  

时间: 2024-10-20 04:57:04

汉诺塔VII(递推,模拟)的相关文章

汉诺塔系列问题: 汉诺塔II、汉诺塔III、汉诺塔IV、汉诺塔V、汉诺塔VI、汉诺塔VII

汉诺塔II:(hdu1207) /先说汉若塔I(经典汉若塔问题),有三塔,A塔从小到大从上至下放有N个盘子,如今要搬到目标C上, 规则小的必需放在大的上面,每次搬一个,求最小步数.这个问题简单,DP:a[n]=a[n-1]+1+a[n-1],先把 上面的n-1个放在B上,把最大的放在目标C上,再把N-1个放回到C上就可以. </pre><p></p>如今是汉若塔II,改为四个塔,開始方程想简单了,不是最优的.给出网上的一种最优解法例如以下:(1)将x(1<=x&l

HDU2.2.3 (汉诺塔VII)

汉诺塔VII Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1574 Accepted Submission(s): 1123   Problem Description n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从

HDU 1997 汉诺塔VII

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1997 Problem Description n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从下往上的大小仍保持如下关系 : n=m+p+qa1>a2>...>amb1>b2>...>bpc1>c2>...>cqai是A柱上的盘的盘号系

hdu1997 汉诺塔VII(DFS递归调用)

题目详情:传送门 我都要做郁闷了,逻辑一直没错,但是最后一组答案就是过不了.看了几个小时,终于发现问题所在了.我把数组初始化 memset() 函数,放在了自定义函数 Input 中,使用形参的sizeof()作为地址的长度,结果数组没有初始化成功,导致悲剧的诞生.之后我把 memset() 中的地址长度改回数组长度问题终于解决了.刚做这一题时我把它当成栈混洗了,结果一直没琢磨明白.之后在网上一查,恍然大悟.霎时间,感觉好难过,为什么自己就没想到.下面我们来分析一下本题的思路吧. 分析: 这一题

汉诺塔VII

HDU1997  题意:排列汉诺塔需要的最小步数是2^N-1  排列过程中会生成2^N个排列,判断一个序列是否发生了额外的移动步数,也就是完成汉诺塔话费的步数多余2^N-1. 模拟法: 1:在正确的排列中,最大的n盘一定在a或c柱上,否则false 2:如果n在a柱上,剩下n-1个盘处在a->b的过程中 3:如果n在c柱上,剩下n-1个盘处在b->c的过程中 4:重复123直到n=0 可以看出是O(N)的时间复杂度. 1 #include <bits/stdc++.h> 2 usi

水题 第四站 HDU 汉诺塔VII

先来回忆一下汉诺塔 A,B,C,三个塔将A塔上的n块砖转移到C塔,首先将(n-1)块砖转移到B塔,将第n块砖转移到C塔,再将B塔上的(n-1)块砖转移到C塔,所以 函数为借助B塔,将A塔的砖转移到C塔, 首先是借助C塔,将A塔的砖转移到B塔, 然后是借助A塔,将B塔的砖转移到C塔. 附上网上的代码,有助于理解,出处 http://blog.csdn.net/kkkkkxiaofei/article/details/8333644/ 1 #include <iostream> 2 #includ

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

HDU2064 汉诺塔III 【递推】

汉诺塔III Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9235    Accepted Submission(s): 4125 Problem Description 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘全部移到右边

Acwing-96-奇怪的汉诺塔(递推)

链接: https://www.acwing.com/problem/content/description/98/ 题意: 汉诺塔问题,条件如下: 1.这里有A.B.C和D四座塔. 2.这里有n个圆盘,n的数量是恒定的. 3.每个圆盘的尺寸都不相同. 4.所有的圆盘在开始时都堆叠在塔A上,且圆盘尺寸从塔顶到塔底逐渐增大. 5.我们需要将所有的圆盘都从塔A转移到塔D上. 6.每次可以移动一个圆盘,当塔为空塔或者塔顶圆盘尺寸大于被移动圆盘时,可将圆盘移至这座塔上. 请你求出将所有圆盘从塔A移动到塔