Description

JZOJ.5285【NOIP2017模拟8.16】排序
 

Input

JZOJ.5285【NOIP2017模拟8.16】排序

Output

JZOJ.5285【NOIP2017模拟8.16】排序
 

Sample Input

5
2 1 5 3 4

Sample Output

5 4 3 1 2
 

Data Constraint

JZOJ.5285【NOIP2017模拟8.16】排序
 

Hint

JZOJ.5285【NOIP2017模拟8.16】排序

感觉像是某年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 }
神奇的代码

相关文章:

  • 2021-08-05
  • 2021-09-05
  • 2022-02-01
  • 2021-06-18
  • 2022-01-15
  • 2021-09-25
  • 2021-06-01
  • 2021-07-28
猜你喜欢
  • 2021-08-25
  • 2022-02-23
  • 2022-03-05
  • 2021-06-18
  • 2022-01-30
  • 2021-07-29
  • 2021-12-13
相关资源
相似解决方案