题意:给出一个不多于64个盘子的汉诺塔的摆法,都已经符合小盘在上大盘在下的规则,需要做的是判断是否为正确摆法。
Analyse:第一眼看下去就觉得是用递归做的,可就是理不顺思路,停停滞滞放了很久,今天终于狠心要搞定它。定义一个递归函数hanoi(n,a1,a2,a3),表示将n个盘子从a1柱移到a3柱。
一、若n在a1,则n-1只能在a1或a2。分两种情况:1、n-1在a1,即要做的是将n-2个盘从a1移到a3,返回hanoi(n-2,a1,a2,a3);2、n-1在a2,即要做的是将n-2个盘从a3移到a2,返回hanoi(n-2,a3,a1,a2);不是这两种情况就返回0.
二、若n在a3,则n-1只能在a2或a3。分两种情况:1、n-1在a2,即要做的是将n-2个盘从a2移到a1,返回hanoi(n-2,a2,a3,a1);2、n-1在a3,即要做的是将n-2个盘从a1移到a3,返回hanoi(n-2,a1,a2,a3);不是这两种情况就返回0.
三、若n在a2,则位置放错了。
判断递归结束的条件是n<=0或n==1且不在a2上。
View Code
1 #include<stdio.h> 2 int pos[70]; 3 int hanoi(int n,int a1,int a2,int a3)//a2为过渡柱,a3为目标柱,flag为真时n只能放在一个特定位置 4 { 5 if(n<=0)return 1; 6 if(n==1 && pos[n]!=a2) 7 return 1; 8 if(pos[n]==a1) 9 { 10 if(pos[n-1]==a1) 11 return hanoi(n-2,a1,a2,a3); 12 if(pos[n-1]==a2) 13 return hanoi(n-2,a3,a1,a2); 14 return 0; 15 } 16 if(pos[n]==a3) 17 { 18 if(pos[n-1]==a2) 19 return hanoi(n-2,a2,a3,a1); 20 if(pos[n-1]==a3) 21 return hanoi(n-2,a1,a2,a3); 22 return 0; 23 } 24 return 0; 25 } 26 int main() 27 { 28 int t,n; 29 int i,j; 30 int temp,num,flag; 31 scanf("%d",&t); 32 while(t--) 33 { 34 scanf("%d",&n); 35 for(i=1;i<=3;i++) 36 { 37 scanf("%d",&num); 38 for(j=0;j<num;j++) 39 { 40 scanf("%d",&temp); 41 pos[temp]=i; 42 } 43 } 44 flag=hanoi(n,1,2,3); 45 printf(flag?"true\n":"false\n"); 46 } 47 return 0; 48 }