描述
给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号,火车站只有一个方向进出,同时停靠在火车站的列车中,只有后进站的出站了,先进站的才能出站。
要求输出所有火车出站的方案,以字典序排序输出。
数据范围:1≤n≤10
进阶:时间复杂度:O(n!) ,空间复杂度:O(n)
输入描述:
第一行输入一个正整数N(0 < N <= 10),第二行包括N个正整数,范围为1到10。
输出描述:
输出以字典序从小到大排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample。
示例1
输入:
3 1 2 3
输出:
1 2 3 1 3 2 2 1 3 2 3 1 3 2 1
说明:
第一种方案:1进、1出、2进、2出、3进、3出 第二种方案:1进、1出、2进、3进、3出、2出 第三种方案:1进、2进、2出、1出、3进、3出 第四种方案:1进、2进、2出、3进、3出、1出 第五种方案:1进、2进、3进、3出、2出、1出 请注意,[3,1,2]这个序列是不可能实现的。
#include<cstdio>
#include<stack>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
/*
思路:
1.求出所有排列组合(全排列)
2.根据入栈序列判断正确的出栈序列
3.对正确的出栈序列按字典排序并输出
*/
vector<string> answer; // 存储全排列结果
int arr_old[20]; //保存入栈序列
bool judge(int arr_in[], string arr_out) //根据入栈序列判断出栈序列是否正确
{
stack<int> mystack;
int j=0;
for(int i=0;i<arr_out.size();i++)//遍历入栈序列
{
// 当前元素入栈
mystack.push(arr_in[i]);
while(mystack.empty()==false && mystack.top()==arr_out[j]-'0')//当前栈顶元素为出栈序列对应元素时,将该元素出栈
{
mystack.pop();
j++;
}
}
return mystack.empty();//栈空,则是正确的出队序列
}
void swap(int arr[],int* a,int* b) // 交换——值传递
{
int temp=*a;
*a=*b;
*b=temp;
}
void perm(int arr[],int begin,int n) // 全排列
{
/*
对数组arr的 下标begin ~ 下标n 的所有元素做全排列:
1) arr:要进行全排列的字符串/数组
2) begin:要进行全排列的第一个元素的下标
3) n:要进行全排列的最后一个元素的下标
*/
// 结束条件:当只剩下一个元素时
if(begin == n)
{
// 记录结果/打印结果
string temp="";
for(int i=0;i<=n;i++)
{
//printf("%d ",arr[i]);
temp.push_back(arr[i]+'0');
}
//在这里进行判断是否满足栈的要求
//printf("\n");
if(judge(arr_old,temp))
{
answer.push_back(temp);
}
}
else {
for(int i=begin;i<=n;i++)
{
// 1)交换第1个元素和第(i+1)个元素:每个元素都在第一个位置进行一次排列
int* a=&arr[begin];//当前要进行全排列的序列的第1个元素
int* b=&arr[i];//第(i+1)个元素
swap(arr,a,b);
// 2)对剩下的第2个到最后一个元素做全排列
perm(arr,begin+1,n);
// 3)把第1个元素和第(i+1)个元素调换回来
swap(arr,a,b);//保证不会有重复的计算
}
}
}
bool compare(string left,string right)
{
if(left < right)
{
return true;
}
else {
return false;
}
}
int main()
{
// 1.输入
int n;
int arr[20];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&arr[i]);
arr_old[i]=arr[i];
}
// 2.全排列
perm(arr, 0, n-1);
// 3.结果按字典排序
sort(answer.begin(),answer.end(),compare);
// 4.输出
for(int i=0;i<answer.size();i++)
{
for(int j=0;j<answer[i].size();j++)
{
printf("%c ",answer[i][j]);
}
printf("\n");
}
}