列车调度问题
描述
某列车调度站的铁道联接结构如Figure 1所示。
其中,A为入口,B为出口,S为中转盲端。所有铁道均为单轨单向式:列车行驶的方向只能是从A到S,再从S到B;另外,不允许超车。因为车厢可在S中驻留,所以它们从B端驶出的次序,可能与从A端驶入的次序不同。不过S的容量有限,同时驻留的车厢不得超过m节。
设某列车由编号依次为{1, 2, …, n}的n节车厢组成。调度员希望知道,按照以上交通规则,这些车厢能否以{a1, a2, …, an}的次序,重新排列后从B端驶出。如果可行,应该以怎样
的次序操作?
输入
共两行。
第一行为两个整数n,m。
第二行为以空格分隔的n个整数,保证为{1, 2, …, n}的一个排列,表示待判断可行性的驶出序列{a1,a2,…,an}。
输出
若驶出序列可行,则输出操作序列,其中push表示车厢从A进入S,pop表示车厢从S进入B,每个操作占一行。
若不可行,则输出No。
样例
Input
5 2
1 2 3 5 4
Output
push
pop
push
pop
push
pop
push
push
pop
pop
限制
1 ≤ n ≤ 1,600,000
0 ≤ m ≤ 1,600,000
时间:2 sec
空间:256 MB
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int a[1600005];
char condition[3200005][5];
int a_len = 0,s_len = 0,c_len = 0;
class SeqStack
{
//顺序栈类定义
private:
int *elements; //数组存放栈元素
int top; //栈顶指示器
int maxSize; //栈最大容量
void overflowProcess(); //栈的溢出处理
public:
SeqStack(int sz); //构造函数
~SeqStack()
{
delete []elements;
}; //析构函数
void Push(int x); //进栈
void Pop(int *x); //出栈
int IsEmpty() const
{
return top == -1;
}
int IsFull() const
{
return top == maxSize-1;
}
int GetSize() const
{
return top+1;
}
int getTop()
{
return elements[top];
}
};
SeqStack::SeqStack(int sz)
{
elements=new int[sz]; //申请连续空间
if(elements==NULL)
{
cout<<"空间申请错误!"<<endl;
exit(1);
}
else
{
top=-1; //栈顶指示器指向栈底
maxSize=sz; //栈的最大空间
};
};
void SeqStack :: overflowProcess()
{
int *newArray = new int[2*maxSize];
for(int i = 0; i<=top; i++)
{
newArray[i] = elements[i];
}
maxSize+=maxSize;
delete []elements;
elements = newArray;
}
void SeqStack::Push(int x)
{
//若栈满,则溢出处理,将元素x插入该栈栈顶
if (IsFull() == 1)
{
overflowProcess();
} //栈满
elements[++top] = x; //栈顶指针先加1, 再元素进栈
s_len++;
strcpy(condition[c_len++],"push");
};
void SeqStack::Pop(int *x)
{
//若栈不空,函数退出栈顶元素并将栈顶元素的值赋给x,
//返回true,否则返回false
if (IsEmpty() == 1)
return ;
*x = elements[top--]; //先取元素,栈顶指针退1
s_len--;
strcpy(condition[c_len++],"pop");
};
int main()
{
int n,m,temp;
cin>>n>>m;
SeqStack s(m);
for(int i=0;i<n;i++)
{
cin>>a[i];
}
for(int i = 1;a_len<n;)
{
if(i<a[a_len])
{
if(m<s_len+1)
{
break;
}
s.Push(i);
i++;
}
else if(i>a[a_len])
{
s.Pop(&temp);
while(temp == a[a_len]&&s_len!=0)
{
a_len++;
if(temp>a[a_len])
{
s.Pop(&temp);
}
}
if(a[a_len]<temp)
{
break;
}
if(i>n||!s_len)
{
a_len++;
}
}
else
{
if(m<s_len+1)
{
break;
}
s.Push(i);
s.Pop(&temp);
a_len++,i++;
}
}
if(a_len!=n)
{
cout<<"No\n";
}
else
{
for(int i=0;i<c_len;i++)
{
puts(condition[i]);
}
}
return 0;
}