题目信息
描述
众所周知Saoirse在某些方面非常神经质,比如无序的数列会让她非常抓狂。
现在她在的剧组门口的小道上停了n辆车,这些车被编号为1~n。这些车从西向东一字排开,最东边一辆车停在T字路口处。
现在比Saoirse更神经质的导演要求把T字路口以西的所有车全部开到十字路口以东。
现在T字路口以西的所有车并没有按照顺序排列,Saoirse希望开到十字路口以东后,所有车从东向西按照升序排列。
但因为路太窄,没法超车,这就给Saoirse造成了一些困扰。
好在,这是一个T字路口,可以有车在T字路口向右拐,开进一条朝南的小巷里,但是最后拐进这条向南的小巷的车必须最先离开这条小巷。
因为这条路太窄了,任何一辆车都不能掉头,也不能两次进入这条向南的小巷。
现在Saoirse在微信上给Primo发了T字路口以南的车的排列序号,现在Primo想请你写一个程序,判断能否通过这条神奇的向南的小巷,让开到T字路口以东的车辆按照顺序排列。
输入
本题有多组测试数据。第一行包括一个正整数n,表示一共有n辆车。下面一行有一个n的排列,所有数都被空格隔开,表示从西向东的车的序号。n不会大于1000,当输入的n为0时,输入数据结束。
输出
对于每组数据,输出yes表示可以完成操作,输出no表示不行。
输入样例 1
5
5 1 2 4 3
0
输出样例 1
yes
解题思路
题目大意
共有n辆车,编号为1 ~ n(顺序打乱),从东向西排列。每次区域A(如图)最右端的一个数有两种选择:
- 进入区域B
- 进入区域C
这两个区域均为先进后出。
我们要求的是,是否能经过若干次操作,将原来区域A中的数正序排列在B区域中。
建立数学模型
其实我们可以把A看成原数组,C看成辅助栈,B看成存储答案的数组。
这样一来,操作1就相当于直接进栈再直接出栈,操作2就是进栈啦~
如此,问题便是:规定入栈序列与出栈序列,求这两个序列是否合法。
易错点
题目不好理解。
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
while (cin >> n && n != 0) {
stack<int> C; // 辅助栈
int cnt = 1;
while (n--) {
int t;
cin >> t;
C.push(t); // 无论如何都要入栈
while (!C.empty() && cnt == C.top()) { // 只要栈顶数目前是应该放到B里的那个数就放
C.pop();
++cnt;
}
}
if (C.empty()) { // 如果能在B正序排列的情况下C里面没有剩余数就可以
cout << "yes\n";
} else {
cout << "no\n";
}
}
return 0;
}