链接 :https://ac.nowcoder.com/acm/contest/22669/A
来源:牛客网
题目描述
给你一个1->n的排列和一个栈,入栈顺序给定
你要在不打乱入栈顺序的情况下,对数组进行从大到小排序
当无法完全排序时,请输出字典序最大的出栈序列
输入描述:
第一行一个数n
第二行n个数,表示入栈的顺序,用空格隔开,结尾无空格
输出描述:
输出一行n个数表示答案,用空格隔开,结尾无空格
示例1
输入
5
2 1 5 3 4
输出
5 4 3 1 2
说明
2入栈;1入栈;5入栈;5出栈;3入栈;4入栈;4出栈;3出栈;1出栈;2出栈
思路: 因为要在不打乱入栈顺序的情况下,尽可能的从大到小排列。在首次操作时,只有取到这组数中的最大值,才能保证字典序最大,在最大值之前的数都放入了栈,接下来,再找最大数后的数中的最大值,因为还要考虑栈顶的元素与之后的最大值比较,栈顶大则输出栈顶,一直大就一直输出,直到栈空或者不满足栈顶大于后面未排数的最大值。最后再将栈中元素依次输出。
我的代码:
#include<bits/stdc++.h>
using namespace std;
stack<int> q;
int main()
{
int n;
cin>>n;
int num[n];
for(int i=0;i<n;i++)
cin>>num[i];
int m=-1;
int k=0;
while(k<n)
{
m=-1;
int j=k,l=k;
for(j;j<n;j++)//找到剩余数字中的最大值
{
m=max(m,num[j]);
}
for(l;l<n;l++)//找最大值的下标
{
if(num[l]==m)
{
if(q.size()>0)//如果最大值小于栈顶元素,且栈不为空
{
while(q.top()>m)//直到最大值大于栈顶元素
{
cout<<q.top()<<" ",q.pop();//输出栈顶元素
if(!q.size()) break;
}
}
cout<<m<<" ";//确保栈顶比最大数小后,且后面的数都比最大值小,输出最大值
break;
}
}
for(int i=k;i<l;i++)
q.push(num[i]);
k=l+1;
}
while(q.size())//依次输出栈中元素
cout<<q.top()<<" ",q.pop();
}
别人代码:
#include<stack>
#include<iostream>
using namespace std;
const int N=1e7+9;
int a[N],b[N];
stack<int> q;
int main()
{
int n;
cin>>n;
//a[i]存入数组
for(int i=0;i<n;i++){
cin>>a[i];
}
//b[i] 第i到n-1位最大的数
for(int i=n-1;i>=0;i--) b[i]=max(a[i],b[i+1]);
//for(int i=0;i<n;i++) cout<<b[i];
//输出可以排序的数
for(int i=0;i<n;i++){
q.push(a[i]);
while(!q.empty()&&q.top()>b[i+1])
{
cout<<q.top()<<" ";
q.pop();
}
}
}
不得不说这样的写法比我的简洁多了,他是先从末开始找到每个区间的最大值,再依次放入栈中,并判断栈顶是否比当前区间的最大值大,大就输出,小就不管,最后再输出栈。简直斯巴拉西。