栈_火车调度

一个火车调度站的容量为n,若入站口有编号为1、2、…、n的n节车厢,编写算法输出n节车厢的所有出站序列。用回溯法设计该问题的递归算法,
调度站当前状态下,只有两种操作:
(1)若入站口车厢非空,则将入站口的k号车厢入栈,进入下一个状态继续试探(递归调用);
(2)若调度站非空,则将栈顶车厢出栈进入出站序列,进入下一个状态继续试探(递归调用);

#include <iostream>
#include<vector>
#include<stack>
using namespace std;
void schedule(vector<int> &a, stack<int> &b, vector<int> &c, int sizec, int starta, int &n)
{
if(sizec == a.size())//完成一种调度,输出调度后的序列
{
for(int i = 0 ; i < a.size() ; i++)
cout << c[i];
cout << endl;
n++;//数量+1
return;
}
if(!b.empty())//如果调度站种有列车,出站
{
c[sizec] = b.top();
b.pop();
schedule(a, b, c, sizec+1, starta, n);//当前状态下的下一步递归
b.push(c[sizec]);//回溯到没出站的状态
}
if(starta < a.size())//如果调度站外还有列车没调度,进站
{
b.push(a[starta]);
schedule(a, b, c, sizec, starta+1, n);//当前状态下的下一步递归
b.pop();//回溯到没进站的状态
}
}

int main() {
const int size = 6;//列车数量
int n = 0;//用以保存序列总数
vector<int> a(size);//为调度列车的数组,值为1,2,3,4,5,6...
for(int i = 0 ; i < size ; i++)a[i] = i+1;
stack<int> b;//用栈模拟调度站
vector<int> c(size,0);//出站序列状态
schedule(a, b, c, 0, 0, n);
cout << n << " sequences" << endl;
}

2、判断序列合法性

#include<iostream>
#include<fstream>
#include<vector>
#include<stack>
using namespace std;

bool check(stack<int> & s, const vector<int> & in, const vector<int> & out, int n)
{
    int j = 0;        //用于表示out的当前值

    for(int i = 0; i < n; i++)
    {
        s.push(in[i]);
        while(!s.empty() && s.top() == out[j])    //这里用while循环来保证有可以出的值时,可以连续出栈
        {
            s.pop();
            j++;
        }
    }

    //如果当前栈不为空,那么确定该组值不合法。
    if(s.empty())
        return true;
    else
        return false;
}

int main(int argc, char **argv)
{
    ifstream fin(argv[1]);
    int n, m;
    while(1)
    {
        fin >> n >> m;
        if( n == 0 && m == 0)
            break;

        vector<int> in;
        for(int i = 1; i <= n; i++)
            in.push_back(i);

        int temp;
        for(int i = 0; i < m; i++)
        {
            stack<int> s;        //局部变量,每次循环后被重置为空
            vector<int> out;
            for(int i = 0; i < n; i++)
            {
                fin >> temp;
                out.push_back(temp);
            }
            if(check(s, in, out, n))
                cout << "YES" << endl;
            else
                cout << "NO" << endl;

        }

    }

    system("pause");
    return 0;
}

3、

#include<iostream>
#include<stack>
using namespace std;
int main() {
  int n,i,j,k=0,num;
  bool hold=false;
  cin>>n;//输入要调节的火车车厢的个数
  stack<int> *a = new stack<int> [n-1];//定义n-1个缓冲轨
  cin>>num;
  cout<<"the "<<num<<" carriage drives into the 1 rail"<<endl;
  a[k].push(num);
  for(i=0;i<n-1;++i){//读取车厢号
    cin>>num;
    for(j=0;j<=k;++j) {
      if(num<a[j].top()) {//如果输入的车厢号比这个缓冲轨的顶部元素小的话,则压入缓冲轨中
        a[j].push(num);
    cout<<"the "<<num<<" carriage drives into the "<<j+1<<" rail"<<endl;
        break;
      }
      if(j==k&&k==n-2){//如果缓冲轨被用了n-1个,还差一个不能驶入其中的话,说明其输入为
        hold=true;     //顺序的1到n,记录为true.
        break;
      }
      if(j==k) {//如果该车厢号不能压入原先的k个缓冲轨中,则压入新的缓冲轨中,并记录使用
        a[k+1].push(num);//缓冲轨的个数k。
    cout<<"the "<<num<<" carriage drives into the "<<k+2<<" rail"<<endl;
        ++k;
        break;
      }
    }
  }
  if(hold==true) {//如果是确认了输入为顺序的1到n,则按照如下方式输出
    for(i=0;i<n-1;++i){
      //cout<<a[i].top()<<" ";
      cout<<"the "<<a[i].top()<<" carriage drives out from the "<<i+1<<" rail"<<endl;
      a[i].pop();
    }
    //cout<<num;//输出最后一个没能入缓冲轨的车厢
    cout<<"the last carriage "<<num<<" was not drove into the rail and it is out"<<endl;
  }
  else {//如果不是顺序期望输入,则按照如下方式输出
  for(i=1;i<=n;++i)
    for(j=0;j<=k;++j){
      if(a[j].empty()==false&&a[j].top()==i) {//在各个缓冲轨中寻找并输出期望车厢号
        //cout<<a[j].top()<<" ";
        cout<<"the "<<a[j].top()<<" carriage drives out from the "<<j+1<<" rail"<<endl;
        a[j].pop();//输出车厢号后弹出缓冲轨
        break;
      }
    }
  }
  return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值