递归:新汉诺塔

递归:新汉诺塔

时间限制: 1 Sec  内存限制: 128 MB

题目描述

    设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号。将这n个圆盘任意的 

    迭套在三根立柱上,立柱的编号分别为A、B、C,这个状态称为初始状态。 

    现在要求找到一种步数最少的移动方案,使得从初始状态转变为目标状态。 

    移动时有如下要求: 

    ◆一次只能移一个盘; 
    ◆不允许把大盘移到小盘上面。 

 

输入

    文件第一行是状态中圆盘总数; 

    第二到第四行分别是初始状态中A、B、C柱上圆盘的个数和从下到上每个圆盘的编号; 

    第五到第七行分别是目标状态中A、B、C柱上圆盘的个数和从下到上每个圆盘的编号。 

 

输出

    每行一步移动方案,格式为:move I from P to Q 
    最后一行输出最少的步数。 

 

样例输入

5
3 3 2 1
2 5 4
0
1 2
3 5 4 3
1 1

 

样例输出

move 1 from A to B
move 2 from A to C
move 1 from B to C
move 3 from A to B
move 1 from C to B
move 2 from C to A
move 1 from B to C
7

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const char ch[4]={'0','A','B','C'};
 6 struct LS{
 7     int begin,end;
 8 }a[51];
 9 int ans=0;
10 void dfs(int x,int y)
11 {
12     if (a[x].begin==y)
13         return;
14     for (int i=x-1;i>=1;i--)
15         dfs(i,6-(a[x].begin+y));
16     printf("move %d from %c to %c\n",x,ch[a[x].begin],ch[y]);
17     a[x].begin=y;
18     ans++;
19 }
20 int main()
21 {
22     int n,m,x;
23     scanf("%d",&n);
24     for (int i=1;i<=3;i++)
25     {
26         scanf("%d",&m);
27         for (int j=1;j<=m;j++)
28         {
29             scanf("%d",&x);
30             a[x].begin=i;
31         }
32     }
33     for (int i=1;i<=3;i++)
34     {
35         scanf("%d",&m);
36         for (int j=1;j<=m;j++)
37         {
38             scanf("%d",&x);
39             a[x].end=i;
40         }
41     }
42     for (int i=n;i>=1;i--)
43         dfs(i,a[i].end);
44     printf("%d\n",ans);
45     return 0;
46 }
hanoi

 

posted @ 2019-06-22 14:32  LHR-LHR  阅读(187)  评论(0编辑  收藏  举报