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轨栈顶) //情况①
{
1、2轨栈顶元素出栈;
记录输出;
}
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;
}