2021-01-20

新汉诺塔(nhanoi)
题目描述
设有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
#include
int n,last[55],first[55],ans=0,m,x;
const char ch[]={‘0’,‘A’,‘B’,‘C’};
//char数组的第一位要有零占位,调了n久呀,一定要吸取教训。
void dfs(int x,int y)
{
if(first[x]==y) return;
for(int i=x-1;i>=1;i–) dfs(i,6-(first[x]+y)); //在要移到的柱子和现在所在柱子之外的柱子中转一下,如要从A移到C,需要先移到B中转!!!
//处理小盘子。
printf(“move %d from %c to %c\n”,x,ch[first[x]],ch[y]);
//输出。
first[x]=y;ans++;
//类似于并查集,找完就将x,y合并,并且累加答案数。
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=3;i++)
{
scanf("%d",&m);
for(int j=1;j<=m;j++) scanf("%d",&x),first[x]=i;
}
for(int i=1;i<=3;i++)
{
scanf("%d",&m);
for(int j=1;j<=m;j++) scanf("%d",&x),last[x]=i;
}
//将每一个目标与初始柱打上标记
for(int i=n;i>=1;i–) dfs(i,last[i]);
//第i个要到目标柱那里去。
printf("%d",ans);
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值