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 }