HDU 1997 汉诺塔VII(递归)

来源:互联网 发布:ise女装官网淘宝网 编辑:程序博客网 时间:2024/05/22 02:25

汉诺塔VII

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)


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个盘子的汉诺塔问题,相信之前碰到过汉诺塔问题的人都应该了解解决汉诺塔问题的递归思想,为了将第n个盘从A移到C,我们势必需要先将前n-1个盘子从A移到B,待第n个盘移动到C之后,再将前n-1个盘子从B移到C,相信这一点理解起来并不是什么大问题

而该题问的就是所给的状态是不是将n个盘子从A移到C过程中必须经历的状态

我们拿n=2来举例

2 0 0      A->B    1 1 0

1 1 0      A->C    0 1 1

0 1 1      B->C    0 0 2

以上是n=2情况过程所出现的所有状态

此题关键在于进一步熟悉每个盘子每一步要移动的选择

我们都知道,第n个盘子从A移动到C,只有两种情况,即第n个盘子要么出现在A柱,要么出现在C柱,如果出现在B柱,就是不正确的移动,直接返回false;否则,递归判断第n-1个盘子的状态。第n-1个盘子的状态与第n个盘子有关,若第n个盘子在A柱,则第n-1个盘子在A柱或B柱,在C柱就是不正确的移动,返回false;若第n个盘子在C柱,则第n-1个盘子则在B柱或C柱,在A柱就是不正确的移动,返回false,就这样一直递归到标号最小的盘子

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<stdio.h>#include<string.h>#include<stdlib.h>#include<queue>#include<math.h>#include<vector>#include<map>#include<set>#include<stdlib.h>#include<cmath>#include<string>#include<algorithm>#include<iostream>#define exp 1e-10using namespace std;const int N = 65;const int inf = 2147483647;const int mod = 2009;int a[N],b[N],c[N],m,p,q;bool hanoi(int t,int n,int i,int j,int k){    if(!n)        return true;    int v=0;    if(i<m&&a[i]==n)        v=1,i++;    if(j<p&&b[j]==n)        v=2,j++;    if(k<q&&c[k]==n)        v=3,k++;    if(v==t)        return false;    return hanoi(6-t-v,n-1,i,j,k);}int main(){    int t,n,i;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        for(i=0;i<m;i++)            scanf("%d",&a[i]);        scanf("%d",&p);        for(i=0;i<p;i++)            scanf("%d",&b[i]);        scanf("%d",&q);        for(i=0;i<q;i++)            scanf("%d",&c[i]);        if(hanoi(2,n,0,0,0))            puts("true");        else            puts("false");    }}

菜鸟成长记


0 0
原创粉丝点击