題目描述
給你一個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;
}