PTA-7.1-列车厢调度(栈的应用)

1.题目要求:

题目点我

2.思路解析:

在这里插入图片描述

样例如图:1-3轨道都可以看成是栈,不论是1轨还是3轨都应该让栈顶指向车厢在轨道的移动方向(因为栈的优点是在栈顶插入和删除元素很方便,反过来的话代码写起来会很麻烦)。

结合图和题目要求的输入,两个输入都应该逆序入栈

主要思路:

由于输入给了原始车厢都在轨1的情况,和最终车厢都进入到轨2的顺序。我们可以从最终车厢都在轨2的情况入手,判断是否会出现不合理的情况。
For example,第一个进入2轨的是C,则C可能有两种来源:①从1轨直接到2轨,②从3轨到2轨。
我们可以更具体地来讨论:
①假如1轨的栈顶就是C,显然C来自1轨 ②3轨栈顶就是C,则来自3轨
③假如不是前两种情况,也不能断定调度出了错误,我们能做的只有把1轨的栈顶出栈,让他进到3轨
④如果1轨已经空则无法进行③的操作,可以直接输出“Are you kidding me?”

再谈代码的思路:

1.先定义一个标记int flag = 1;假定按输入的调度方式不会出现问题。当出问题了再将标记赋为0.
2.以2轨最终状态为入手点,从第一个进2轨的到最后一个进2轨的 逐个遍历,按上面的①~④进行操作并逐个出栈——直到2轨中的元素全部出栈则代表没问题,或遇到④情况直接输出"Are you kidding me?"

while(2轨不空)
{
	if(1轨栈顶 == 2轨栈顶)	//情况①
	{
		12轨栈顶元素出栈;
		记录输出;
	}
	else if(3轨栈顶 == 2轨栈顶)//情况②
	{
		3/2轨栈顶元素出栈;
		记录输出;
	}
	else if(1轨非空)//情况④
	{
		1轨栈顶元素出栈,并将其入到3;
		记录输出;
	}else//情况③
	{
		flag = 0;
		break;
	}
}

3.关于输出:由于在执行完while()循环之前你不知道他给出的调度顺序是正确的还是错误的,如果错误就只输出kidding而不输出1->2之类的操作序列了,应当把操作序列先存起来(比如用string数组)最后一块儿输出。

3.代码:

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
#define STACK_INIT_SIZE 100
#define INCRESEMENT 10
typedef char ElemType;
typedef int Status;
typedef struct Stack {
	ElemType* top;
	ElemType* base;
	int stacksize;//当前已分配的存储空间
}Stack;
void StackInit(Stack& s) {//初始化
	s.stacksize = STACK_INIT_SIZE;
	s.top = s.base = (ElemType*)malloc(sizeof(ElemType) * s.stacksize);
}
void Push(Stack& s, ElemType e) {//入栈
	if (s.top - s.base >= s.stacksize) {//栈满
		s.base = (ElemType*)realloc(s.base, sizeof(ElemType) * (s.stacksize + INCRESEMENT));
		s.top = s.base + s.stacksize;
		s.stacksize += INCRESEMENT;
	}
	*s.top = e;
	s.top++;
}
bool Empty(Stack s) {//判空
	if (s.top == s.base)
		return 1;
	return 0;
}
ElemType Pop(Stack& s) {//返回值为弹出元素
	if (Empty(s))
		return '0';
	else {
		s.top--;
		ElemType e = *s.top;
		return e;
	}
}
ElemType Top(Stack& s) {//返回栈顶元素
	if (Empty(s))
		return '0';
	else {
		ElemType e = *(s.top - 1);
		return e;
	}
}
int main() {
	string a, b;
	cin >> a >> b;
	Stack s1, s2, s3;//三个轨道
	StackInit(s1);
	StackInit(s2);
	StackInit(s3);
	string road[100];//记录输出的路径
	int cnt = 0;//有几行输出
	int flag = 1;
	for (int i = a.size()-1; i >= 0; i--) {//两组输入都要逆序入栈
		Push(s1, a[i]);
	}
	for (int i = b.size()-1; i >= 0; i--) {
		Push(s2, b[i]);
	}
	while (!Empty(s2)) {//2轨不空
		if (!Empty(s1) && Top(s1) == Top(s2)) {//2轨的当前元素显然来自1轨
			Pop(s1);
			Pop(s2);
			road[++cnt] = "1->2";
		}
		else if (!Empty(s3) && Top(s3) == Top(s2)) {//2轨的当前元素显然来自3轨
			Pop(s3);
			Pop(s2);
			road[++cnt] = "3->2";
		}
		else if (Empty(s1)) {//没有别的选择,这个调度肯定是出了问题
			flag = 0;
			break;
		}
		else {//如果不是①②两种情况,不要断定出错,要先拖延时间
			char e = Top(s1);
			Pop(s1);
			Push(s3,e);
			road[++cnt] = "1->3";
		}
	}
	if (!flag)
		cout << "Are you kidding me?" << endl;
	else {
		for (int i = 1; i <= cnt; i++) {
			cout << road[i] << endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值