hdu1997 汉诺塔VII(深度优先搜索)

来源:互联网 发布:java web项目多线程 编辑:程序博客网 时间:2024/05/18 03:33
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
631 31 21 131 31 11 263 6 5 41 12 3 263 6 5 42 3 21 131 31 21 1202 20 172 19 1816 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
 
Sample Output
truefalsefalsefalsetruetrue
 
做这道题之前,我们首先应该知道的一个问题,汉诺塔问题代码的原理是什么?
假设一共有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;}


0 0
原创粉丝点击