设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号。将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A、B、C,这个状态称为初始状态。
现在要求找到一种步数最少的移动方案,使得从初始状态转变为目标状态。
移动时有如下要求:
·一次只能移一个盘;
·不允许把大盘移到小盘上面。
从洛谷上找来的题解,没有时间做,但还是觉得这题挺好
1 #include<cstdio> 2 int n,last[55],first[55],ans=0,m,x; 3 const char ch[]={'0','A','B','C'}; 4 //char数组的第一位要有零占位,调了n久呀,一定要吸取教训。 5 void dfs(int x,int y) 6 { 7 if(first[x]==y) return; 8 for(int i=x-1;i>=1;i--) dfs(i,6-(first[x]+y)); 9 //处理小盘子。 10 printf("move %d from %c to %c\n",x,ch[first[x]],ch[y]); 11 //输出。 12 first[x]=y;ans++; 13 //类似于并查集,找完就将x,y合并,并且累加答案数。 14 } 15 int main() 16 { 17 scanf("%d",&n); 18 for(int i=1;i<=3;i++) 19 { 20 scanf("%d",&m); 21 for(int j=1;j<=m;j++) scanf("%d",&x),first[x]=i; 22 } 23 for(int i=1;i<=3;i++) 24 { 25 scanf("%d",&m); 26 for(int j=1;j<=m;j++) scanf("%d",&x),last[x]=i; 27 } 28 //将每一个目标与初始柱打上标记 29 for(int i=n;i>=1;i--) dfs(i,last[i]); 30 //第i个要到目标柱那里去。 31 printf("%d",ans); 32 return 0; 33 }