用双向链表解“栈混洗”问题-火车调度C++

问题描述:其中,A为入口,B为出口,S为中转盲端。所有铁道均为单轨单向式:列车行驶的方向只能是从A到S,再从S到B;另外,不允许超车。因为车厢可在S中驻留,所以它们从B端驶出的次序,可能与从A端驶入的次序不同。不过S的容量有限,同时驻留的车厢不得超过m节。
设某列车由编号依次为{1, 2, …, n}的n节车厢组成。调度员希望知道,按照以上交通规则,这些车厢能否以{a1, a2, …, an}的次序,重新排列后从B端驶出。如果可行,应该以怎样的次序操作?
问题描述

基本功能:输入包含几个测试用例。每个测试用例由列车数量、一个整数和一个字符串组成,列车的顺序为:O1。输入在文件结束时终止。
输出包含字符串“No”。如果您不能将O2转换为O1,或者您应该输出您交换订单的方式(您应该输出“push”表示列车进入铁路,输出“pop”表示列车离开铁路)。
(更多信息参考输入输出样例)

测试数据:
Sample Input
5 2
1 2 3 5 4

5 5
3 1 2 4 5

Sample Output
push
pop
push
pop
push
pop
push
push
pop
pop

No

实现逻辑:对于第一个样本输入,我们让第1列进入,然后让第1列离开。然后是让第2列进入,再让第2列离开。第3列进入,3号列车离开。4号列车,5号列车依次进入,最后依次离开。
在第二个样本输入中,我们应该让3号列车先离开,所以我们必须让1号列车进站,然后让2号列车和3号列车进站。
现在我们可以让3号火车离开了。
但在那之后,我们不能让1号列车在2号列车之前离开,因为2号列车目前在铁路的顶端。
所以我们输出“No.”。

代码内容:

//1-n编号车厢按照“栈混洗”从A->S->B,最终确认车厢B处是否可以按照某一序列排列
//一种栈结构输出不要用strcat进行字符链接输出(会TLE)
//双向链表模拟

#include<iostream>
#include<string>
using namespace std;

#define MAX 1600005

//A->S->B
/*构建双向链表*/
struct Train {
    
    
	int num;
	Train* up;
	Train* down;
	Train(int n) :num(n) {
    
    }
}*header, * tailer;//前后哨兵

int target[MAX];
bool output[2 * MAX];
int k;

/*构建*/
void Creat_Train(int n) {
    
    
	header = new Train(0);
	header->up = NULL;

	Train* rear = header;//定义尾针
	for (int i = 1; i <= n; i++) {
    
    
		Train* p = new Train(i);//新链表元素
		rear->down = p;
		p->up = rear;

		rear = p;
	}
	tailer = new Train(0);
	rear->down = tailer;
	tailer->up = rear;
	tailer->down = NULL;
}

/*删除*/
void Delete(Train* p) {
    
    
	p->up->down = p->down;
	p->down->up = p->up;
	delete p;
}

int main() {
    
    
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)//目标序列
		cin >> target[i];

	Creat_Train(n);

	int counter = 0;//s站车厢数量
	Train* cur = header->down;
	/*开始匹配第i个目标车厢*/
	for (int i = 1; i <= n; i++) {
    
    
		if (cur->num == target[i]) {
    
    //A栈顶匹配
			Train* tmp = cur;
			cur = cur->down;
			Delete(tmp);//删除车厢结点
			if (counter + 1 > m) {
    
    //s滞留车厢过多
				cout << "No\n";
				return 0;
			}
			output[k++] = true;
			output[k++] = false;
		}
		else if (cur->up->num == target[i]) {
    
    //s栈顶匹配
			Delete(cur->up);
			output[k++] = false;
			counter--;
		}
		else {
    
    //A->S
			cur = cur->down;
			--i;
			counter--;
			if (cur->down == NULL || counter > m) {
    
    //A空或s滞留车厢过多
				cout << "No\n";
				return 0;
			}
			output[k++] = true;
		}
	}
	/*Output*/
	for (int i = 0; i < k; i++) {
    
    
		if (output[i]) cout << "push\n";
		else cout << "pop\n";
	}
	return 0;
}

测试例1
测试例2
参考https://www.cnblogs.com/Inkblots/p/4950331.html

猜你喜欢

转载自blog.csdn.net/cwindyc/article/details/106159526