新汉诺塔

emmm,今天我们考递归,总体来讲还好,但是最后一道奇怪的汉诺塔根本没看,没想到固输得分了!!!哈哈哈!!!

题目:

新汉诺塔(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 <iostream>
#include <cstring>
using namespace std;
int step;
char  s[4]={' ','A','B','C'};
int xian[64],yuan[64],n;
void mov(int c,int b) //c盘子想挪到b 
{
    int x,l;
    if (b==yuan[c]) return;
    x=6-b-yuan[c];  //x为剩下的那个柱子
    for (l=c-1;l>=1;l--)  mov(l,x); //把比c盘子小的小盘子挪到x柱上 
    cout<<"move "<<c<<" from "<<s[yuan[c]]<<" to "<<s[b]<<endl;
    yuan[c]=b;
    step++;
}
int main()
{
    cin>>n;
    int k,l;
    for (int i=1;i<=3;i++)
    {
        cin>>k;
        for (int j=1;j<=k;j++)
        {
            cin>>l;
            yuan[l]=i;  //n个盘子原来在哪 
        }
    }
    for (int i=1;i<=3;i++)
    {
        cin>>k;
        for (int j=1;j<=k;j++)
        {
            cin>>l;
            xian[l]=i; //n个盘子将要去哪 
        }
    }
    for (int i=n;i>=1;i--)  //倒着移动,因为大盘子不影响小盘子 
    mov(i,xian[i]);
    cout<<step<<endl;
    return 0;
}

 

posted @ 2018-02-25 21:20  DukeLv  阅读(994)  评论(1编辑  收藏  举报