華爲OJ【問題描述】
給定一個正整數N代表火車數量,0< N<10,接下來輸入火車入站的序列,一共N輛火車,每輛火車以數字1-9編號。要求以字典序排序輸出火車出站的序列號。
輸入:
有多組測試用例,每一組第一行輸入一個正整數N(0< N<10),第二行包括N個正整數,範圍爲1到9。
輸出:
輸出以字典序排序的火車出站序列號,每個編號以空格隔開,每個輸出序列換行,具體見sample。
樣例輸入:
3
1 2 3
樣例輸出:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
解題思路:此題的本質就是給你一個入棧序列,求出其所有出棧序列的情況。根據樣例輸出,我們可以觀察出這可能是一個數組的全排列過程,只是少了部分情況,而那部分情況就是不滿足出棧序列的,比如3 1 2,若先出3,則1 2在棧裏,此時再出 1 就不滿足出棧序列了。所以:當對數組全排列以後,在輸出階段,再判斷此排列是否滿足出棧序列,即從當前值開始,後序所有的值爲降序排列,就符合出棧,否則,不符合。代碼如下:
#include <iostream>
#include<string>
#include<vector>
#include<algorithm>
#include <fstream>
using namespace std;
void PrintNum(vector<int>);
void Perm(vector<int> &data,int start)
{
if(start == data.size()-1)
{
PrintNum(data);
return;
}
for(int i = start;i < data.size();++i)
{
swap(data[i],data[start]);
Perm(data,start+1);
swap(data[i],data[start]);
}
}
void PrintNum(vector<int> data)
{
int size = data.size();
int m_small = 0;
bool flag = true;
for(int i = 0;i < size;++i)
{
int curr_small = 0;
for(int j = i+1;j < size && flag;++j)
{
if(data[i] > data[j])//不能只要data[i] > data[j]就更新較小的值,應該判斷的是較小值後面的值是否降序,所以只記錄當前i中第一個比data[i]小的值
{
if(curr_small == 0) //記錄當前第一個比data[i]小的值,用於判斷後面的值是否是降序,滿足出棧要求
m_small = data[j],++curr_small;
else
{
if(data[j] > m_small) //如果之後出現的數比記錄的數還大,改變flag
flag = false;
else //否則記錄這個更小的數
m_small = data[j];
}
}
}
}
if(flag)
{
for(int i = 0;i < size;++i)
{
cout<<data[i]<<" ";
}
cout<<endl;
}
}
int main()
{
vector<int> data(3,0);
data[0] = 1;
data[1] = 2;
data[2] = 3;
Perm(data,0);
}