解题思路:首先我来解释下汉诺塔的移动思想,要把左边的最下面的盘放到右边的最下面(即编号为n的盘),那前提是,其他的都按照顺序呢放在了中间,又因为则第n个盘已经在右边的最下面了,所以就不用再管了,则重新把n-1当最最大的,则现在只要把中间看做左边的,左边看做中间的就行,这样就一次次递归下去了;
这里的主要突破点在,最大的盘都是直接从左边到右边的,即不能出现最大的盘在中间的情况,如出现,则直接放回false。
代码如下:
#include
#include
int flag;
void dfs(int n,int a[],int b[],int c[])
{
int i;
if(n==0){
flag=1;return;
}
if(n==b[1]){
flag=0;return;
}
if(a[1]==n){
for(i=1;i
a[i]=a[i+1]; //最大盘n已经在右边的最下面了,所以不需要再看了,
dfs(n-1,a,c,b); //当n编号的盘在X上时,应把n编号前面的盘现移到Y中
}else if(c[1]==n){
for(i=1;i
c[i]=c[i+1];
dfs(n-1,b,a,c); //当n编号的盘在Z上市,则把Y看做X;
}
}
int main()
{
int T,n;
int a[100],b[100],c[100],i,j,m;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
flag=0;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
scanf("%d",&n);
scanf("%d",&m);
for(i=1;i<=m;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(i=1;i<=m;i++)
scanf("%d",&b[i]);
scanf("%d",&m);
for(i=1;i<=m;i++)
scanf("%d",&c[i]);
dfs(n,a,b,c);
if(flag)
printf("true\n");
else printf("false\n");
}
}
}