hdu1997 汉诺塔VII(深度优先搜索)
2016-08-06 17:48
225 查看
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个圆盘与其他n-1个圆盘分开看。首先,将其他n-1个圆盘移到B圆盘,再把第n个圆盘移到C圆盘,最后将在B上的那n-1个圆盘集体移到C上就完成了整个过程。在这里给大家张贴一段代码,这个代码也是最简单的汉诺塔问题,即,如何将n个圆盘从最左边的A杆移动到左右侧的C杆,需要经历怎样的步骤,代码如下:
而本题是这个问题的一个延伸,用的是深度优先搜索的方法,还有一些分治的思想。我们还是要从最下面的那个第n个圆盘入手,当你想将n个圆盘从A圆盘移动到C圆盘的时候,你得先将另外n-1个圆盘移动到B,再把A移动到C,这是最简单的方式。因此,你肯定不能将第n个圆盘移动到B圆盘上,否则,就这道题而言就是不正确的。那另外两种情况呢?
首先是第n个圆盘再A杆上,此时就是之前说的:其他n-1个圆盘移到B圆盘,再把第n个圆盘移到C圆盘,最后将在B上的那n-1个圆盘集体移到C上。
要是第n个圆盘再C上的话,你只需将另外在n-1个圆盘直接移到C上即可。
相关解释,在代码中已经给出了解释:
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个圆盘与其他n-1个圆盘分开看。首先,将其他n-1个圆盘移到B圆盘,再把第n个圆盘移到C圆盘,最后将在B上的那n-1个圆盘集体移到C上就完成了整个过程。在这里给大家张贴一段代码,这个代码也是最简单的汉诺塔问题,即,如何将n个圆盘从最左边的A杆移动到左右侧的C杆,需要经历怎样的步骤,代码如下:
//Hanoi Problem #include<iostream> using namespace std; void Hanoi(int n,char A,char B,char C) { if(1==n) ///如果A上只剩下1个圆盘的时候,直接把这个圆盘从A移到C即可 { cout<<"从"<<A<<"移到"<<C<<endl; } else { Hanoi(n-1,A,C,B);///先将另外n-1个圆盘从A借助C移动到B cout<<"从"<<A<<"移到"<<C<<endl;///第n个圆盘从A移到C Hanoi(n-1,B,A,C);///再将n-1个圆盘从B借助A移到C } } int main() { Hanoi(3,'A','B','C'); return 0; }以上代码的运行结果是(当然了,每次都是那对应杆上的最上面的那个圆盘):
而本题是这个问题的一个延伸,用的是深度优先搜索的方法,还有一些分治的思想。我们还是要从最下面的那个第n个圆盘入手,当你想将n个圆盘从A圆盘移动到C圆盘的时候,你得先将另外n-1个圆盘移动到B,再把A移动到C,这是最简单的方式。因此,你肯定不能将第n个圆盘移动到B圆盘上,否则,就这道题而言就是不正确的。那另外两种情况呢?
首先是第n个圆盘再A杆上,此时就是之前说的:其他n-1个圆盘移到B圆盘,再把第n个圆盘移到C圆盘,最后将在B上的那n-1个圆盘集体移到C上。
要是第n个圆盘再C上的话,你只需将另外在n-1个圆盘直接移到C上即可。
相关解释,在代码中已经给出了解释:
#include<iostream> using namespace std; bool DFS(int n,int A[],int B[],int C[])///将n个圆盘从A杆借助B杆从而移到C杆 { if(B[0]==n)///如果第n个盘在B杆上的话,就多步骤了,这是不正确的 { return false; } else if(A[0]==n) ///如果第n个圆盘在A杆上 { return DFS(n-1,A+1,C,B);///将第n个圆盘上方(所以是A+1)的n-1个圆盘借助C移到B上 } else if(C[0]==n) ///如果第n个圆盘在C杆上 { return DFS(n-1,B,A,C+1);///将B上的n-1个圆盘借助A移到C杆上,且在第n个圆盘的上方(所以是C+1) } return true; } int main() { int A[70],B[70],C[70]; int testNum; int n,m,p,q; cin>>testNum; while(testNum--) { cin>>n; cin>>m; for(int i=0;i<m;i++) { cin>>A[i]; } cin>>p; for(int i=0;i<p;i++) { cin>>B[i]; } cin>>q; for(int i=0;i<q;i++) { cin>>C[i]; } if(DFS(n,A,B,C)) { cout<<"true"<<endl; } else { cout<<"false"<<endl; } } return 0; }
相关文章推荐
- 【(伪)递归】HDU1997 - 汉诺塔VII(非递归解法)
- hdu1997 汉诺塔VII(DFS递归调用)
- 汉诺塔问题 hdu 2064 && hdu1997
- HDU 1997 汉诺塔VII
- 【杭电】[1997]汉诺塔VII
- HDU 1997 - 汉诺塔VII
- HDU 1997 汉诺塔VII
- 汉诺塔VII
- HDU 汉诺塔VII
- HDU 1997 汉诺塔VII(递归)
- hdu(1997) 汉诺塔VII
- HDU2.2.3 (汉诺塔VII)
- hdu 1997 汉诺塔vii
- HDU:汉诺塔VII 终于做出来了!
- HDU 1997 汉诺塔VII
- HDU 1997 汉诺塔VII
- HDOJ 1997 汉诺塔VII 【递归】
- HDU 1997 汉诺塔VII (模拟)
- 汉诺塔系列问题: 汉诺塔II、汉诺塔III、汉诺塔IV、汉诺塔V、汉诺塔VI、汉诺塔VII
- 深度优先搜索 hdu 1997 汉诺塔问题