P1242 【新汉诺塔】

设有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 }

猜你喜欢

转载自www.cnblogs.com/zytwan/p/9931225.html