新汉诺塔

题目描述

设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号。将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A、B、C,这个状态称为初始状态。

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

移动时有如下要求:

·一次只能移一个盘;

·不允许把大盘移到小盘上面。

输入输出格式

输入格式:

 

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

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

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

 

输出格式:

 

每行一步移动方案,格式为:move I from P to Q

最后一行输出最少的步数。

 

输入输出样例

输入样例#1: 复制
5
3 3 2 1
2 5 4
0
1 2
3 5 4 3
1 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

说明

圆盘总数≤45

首先要将第n个盘子从x到y

那么就要把比n小的盘子全部移到6-x-y

递归处理

然后将n移到y

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int a[101],b[101],n;
 7 long long ans;
 8 void dfs(int x,int des)
 9 {int i;
10     if (a[x]==des) return;
11     for (i=x-1;i>=1;i--)
12     dfs(i,6-des-a[x]);
13     printf("move %d from %c to %c\n",x,a[x]+64,des+64);
14     a[x]=des;ans++;
15 }
16 int main()
17 {int x,i,d;
18     cin>>n;
19     cin>>x;
20     for (i=1;i<=x;i++)
21     {scanf("%d",&d);a[d]=1;}
22     cin>>x;
23     for (i=1;i<=x;i++)
24     {scanf("%d",&d);a[d]=2;}
25     cin>>x;
26     for (i=1;i<=x;i++)
27     {scanf("%d",&d);a[d]=3;}
28     
29     cin>>x;
30     for (i=1;i<=x;i++)
31     {scanf("%d",&d);b[d]=1;}
32     cin>>x;
33     for (i=1;i<=x;i++)
34     {scanf("%d",&d);b[d]=2;}
35     cin>>x;
36     for (i=1;i<=x;i++)
37     {scanf("%d",&d);b[d]=3;}
38     
39     for (i=n;i>=1;i--)
40     dfs(i,b[i]);
41     cout<<ans;
42 }

 

posted @ 2017-11-05 13:44  Z-Y-Y-S  阅读(406)  评论(0编辑  收藏  举报