您的位置:首页 > 其它

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杆,需要经历怎样的步骤,代码如下:
//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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: