JZOJ.5285【NOIP2017模拟8.16】排序

Description

 

Input

Output

 

Sample Input

5
2 1 5 3 4

Sample Output

5 4 3 1 2
 

Data Constraint

 

Hint

感觉像是某年NOIP的双栈排序的弱化版......

这题要求字典序最大,我们采用贪心做法,我们可以证明这是正确的。

考虑每一位的数字,我们尽可能地让它大,很明显第一位一定能保证是最大值。

那么对于第二位我们当然想让它为第二大的数字,如果这个数字不在栈里面,那么我们可以等待它进栈后再弹出,但如果已经在栈里面,但在栈顶部,我们也可以弹出,但不在栈的顶部,那么无论如何我们都不可能让它弹出来作为第二位了,那么我们期望第三大的数字作为第三位,重复上面的步骤即可。当我们期望的数变成了0,说明已经没有元素还没有进过栈了,我们可以直接把栈里的元素弹出即可。复杂度O(n).

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #define N 2000005
 8 using namespace std;
 9 int zhan[N],top,now,qwq,dui[N],n;
10 bool in[N];
11 int main(){
12     memset(in,false,sizeof(in));
13     scanf("%d",&n);
14     for (int i=1;i<=n;i++)
15      scanf("%d",&dui[i]);
16     qwq=0;
17     top=0;
18     now=n;
19     while(qwq!=n){
20         zhan[++top]=dui[++qwq];
21         in[dui[qwq]]=true;
22         if (qwq==n) break;
23         if (zhan[top]==now){
24             printf("%d ",zhan[top]);
25             top--;
26             now--;
27             while (true){
28                 if (zhan[top]>=now){
29                     printf("%d ",zhan[top]);
30                     top--;
31                     if (zhan[top+1]==now) now--;
32                     continue;
33                 }
34                 if (!in[now]) break;
35                 now--;
36             } 
37         }
38         if (now==0) break;
39     }
40     for (int i=top;i>0;i--)
41         printf("%d ",zhan[i]);
42     return 0;
43 }
神奇的代码

 

posted @ 2017-08-16 19:10  ~Lanly~  阅读(276)  评论(0编辑  收藏  举报