汉诺塔(火车掉头)-课程设计

本文介绍了一个使用递归方法实现铁路车头顺序反转的程序设计问题。通过定义三个栈来模拟三段铁路轨道,并利用递归函数将车头顺序颠倒,解决了特定条件下车头调度的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


跟我两个队友一起,我们三个一组,每个组都要有高低分。他俩都是拿专业前三的人,都比较看重分数,反正我对成绩也不在乎,就让给他俩了,所以就给了我一个简单的题。

不过既然做了,就想做好点吧。


下面铁路线A段中,有n个车头,按图中所示的顺序编号为1,2,...,n。每个车头都可以在铁路上独立行驶,但约定,当B段或C段已有车头时,新进入这二段的车头号必须比该段中已有的车头号小。设计一个程序,调用递归过程,将A段中车头的顺序颠倒过来。


ps:图放不上,就不放了;


#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
stack<int>a;  //a为x轨道;
stack<int>b;  //b为y轨道
stack<int>c;  //c为z轨道;
void move(int x,int y)  //车厢转移;
{
    int t;
    switch(x)  //选择从哪个轨道上拿出一个车厢;
    {
        case 1:
            t=a.top();  //提取车厢;
            a.pop();  //删除车厢;
            break;
        case 2:
            t=b.top();
            b.pop();
            break;
        case 3:
            t=c.top();
            c.pop();
            break;
    }
    switch(y)  //把拿出来的车厢放在哪个轨道上;
    {
        case 1:
            a.push(t);  //将车厢放入;
            break;
        case 2:
            b.push(t);
            break;
        case 3:
            c.push(t);
            break;
    }
}
void fun(int n,int x,int y,int z)  //递归函数,把x轨道上1到n的车厢转移到z轨道上,y轨道作为辅助轨道;
{
    if(n==1)
    {
        move(x,z);  //把x轨道头上的一节车厢转移到z轨道上;
    }
    else
    {
        fun(n-1,x,z,y);  //把x轨道上1到n-1号车厢转移到y轨道上,z轨道作为辅助轨道;
        move(x,z);  //把x轨道头上的一节车厢转移到z轨道上;
        fun(n-1,y,x,z);  //把y轨道上1到n-1号车厢转移到z轨道上,x轨道作为辅助轨道;
    }
}
/*******************************************************************
    从n=25开始,程序就慢了,毕竟是递归,时间复杂度挺高的;
    经过多次测试:

        n==22时,平均用时 1.224s;
        n==23时,平均用时 1.875s;
        n==24时,平均用时 2.232s;
        n==25时,平均用时 2.941s;
        n==26时,平均用时 5.630s;

    所以测试的时候,n不要输入太大,否则不出结果;
*******************************************************************/
int main()
{
    int n,x=1,y=2,z=3;  //n数车厢的数量,x,y,z分别是轨道名称;
    cout<<"输入车厢数量:"<<endl;
    cin>>n;  //输入车厢的数量;
    for(int i=n; i>=1; i--) a.push(i);  //把车厢倒着放入x轨道;
    fun(n,x,y,z);  //调用递归函数;
    cout<<"调整后车厢号输出:"<<endl;
    for(int i=1; i<=n; i++)  //输出在c轨道上的车厢;
    {
        printf("%4d  ",c.top());  //输出顶端的数,并控制输出格式;
        c.pop();  //删除顶端的数;
        if(i%10==0) cout<<endl;  //10个数一行,用来换行;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值