题解 | #火车进站#
火车进站
https://www.nowcoder.com/practice/97ba57c35e9f4749826dc3befaeae109
方法:使用双栈(一个正向栈,一个反向栈(vector版))+next_permutation
首先介绍next_permutation: 非常好用的用于输出按字典序的全排列组合。可以对vector,int[]数组等进行重排操作
接下来讲述本题思路:
- 首先使用反向栈存储车辆编号记录车辆出现顺序trains,这里使用vector将新编号车辆插入头部,每次取最后一个元素,取完pop_back,即可实现
- 之后对order进行从小到大排序(为了按字典序输出,并输出所有可能序列)
- 再然后,对于给定反向栈trains与可能序列order,遍历order,
对于某一元素:id:
- 若栈station为空,则从反向栈trains中取元素放入station中直至出现id,弹出元素并移至下一id
- 若栈station不空,首先判断id是否为栈station顶端元素,
- 否:判断id是否仍在trains里
- 是,执行类似a操作,从trains中取元素放入station直至出现id,弹出元素并移至下一id
- 否,则说明该order不可能出现
- 是:弹出栈顶元素,移至下一id
#include <algorithm> #include <iostream> #include <iterator> #include <stack> #include <vector> using namespace std; bool find(vector<int> trains, int id) { if(size(trains) == 0) return false; for (int i = 0; i < size(trains); i ++) { if (id == trains[i]) return true; } return false; } void show_plans(vector<int> plans){ for(int i = 0; i < size(plans); i ++) cout << plans[i] << " "; cout << endl; } int main() { int nums = 0; cin >> nums; vector<int> trains; vector<int> orders; for (int i = 0; i < nums; i ++) { int id = 0; cin >> id; trains.insert(trains.begin(), id); orders.push_back(id); } sort(orders.begin(),orders.end()); do { bool flag = true; stack<int> station; int len = size(orders); vector<int> temp = trains; for (int i = 0; i < len; ) { int id = orders[i]; if (station.empty()) { int first = temp[size(temp) - 1]; while (first != id) { station.push(first); temp.pop_back(); first = temp[size(temp) - 1]; } temp.pop_back(); i ++; } else { if (station.top() != id) { if (find(temp, id)) { int first = temp[size(temp) - 1]; while (first != id) { station.push(first); temp.pop_back(); first = temp[size(temp) - 1]; } temp.pop_back(); i ++; }else{ flag = false; break; } }else{ station.pop(); i ++; } } } if(flag) show_plans(orders); } while (next_permutation(orders.begin(), orders.end())); } // 64 位输出请用 printf("%lld")