题目描述
给你一个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 <stdio.h>
#include <iostream>
using namespace std;
const int maxn = 1e6 + 5;
int n, cnt = 0;
int a[maxn], c[maxn * 4], sta[maxn]; //栈和树状数组以及栈
int lowbit(int x){return x & (-x);}
//获得某个区间的最大值
int query(int l, int r){
int ans=a[r];
while(l!=r)
{
for(--r;r>=l+lowbit(r);r-=lowbit(r))
{
ans=max(ans,c[r]);
}
ans=max(ans,a[r]);
}
return ans;
}
//将x位置修改为p
void update(int x, int p){
while(x <= n){
c[x] = a[x];
for(int i = 1; i < lowbit(x); i<<=1){
c[x] = max(h[x], c[x - i]);
}
x += lowbit(x);
}
}
void test(){
n = 9;
int t[] = {0,1,3,4,8,5,6,9,7,2};
for(int i = 1; i <= 9; i++){
update(i, t[i]);
}
printf("%d %d %d",query(1, 9), query(5, 5), query(6, 9));
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++){
int x;
scanf("%d", &x);
update(i, x);
}
int maxv = n;
for(int i = 1; i <= n; i++){
if(a[i] == maxv){ //等于最大值就直接输出
if(i != n - 1)
printf("%d ", maxv);
else printf("%d\n", maxv);
maxv = query(i, n); //查询下个区间的最大值
}else{
sta[cnt++] = a[i]; //否则入栈;
}
}
//出栈
for(--cnt; cnt > 0;cnt--){
printf("%d ", sta[cnt]);
}
printf("%d\n", sta[0]);
return 0;
}