棧和排序(字典序最大的出棧序列)


 

鏈接:https://ac.nowcoder.com/acm/problem/14893
來源:牛客網

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld

題目描述

給你一個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出棧

 

要讓字典序最大就要讓大的數盡量先出棧。

用一個數組rmax[i]表示第 i 項到第 n 項的數的最大值。

如果棧頂元索大於第i項到第n項的最大值,那么直接讓這個元索出棧,讓大的先出棧總能保證字典序最大。

如果棧頂元素小於第 i 項到第 n 項的最大值,那就讓該元素入棧,等着后面更大的元素。

如果最后所有元素都已經入棧了,記得還要輸出棧內剩余的元素。

 

代碼如下:

 1 #include <bits/stdc++.h>
 2 typedef long long LL;
 3 #define pb push_back
 4 #define mst(a) memset(a,0,sizeof(a))
 5 const int INF = 0x3f3f3f3f;
 6 const double eps = 1e-8;
 7 const int mod = 1e9+7;
 8 const int maxn = 1e6+10;
 9 using namespace std;
10 
11 int a[maxn];
12 int rmax[maxn];
13 stack<int> sk;
14 vector<int> vt;
15 
16 int main()
17 {
18     #ifdef DEBUG
19     freopen("sample.txt","r",stdin); //freopen("data.out", "w", stdout);
20     #endif
21     
22     int n;
23     scanf("%d",&n);
24     for(int i=1;i<=n;i++)
25         scanf("%d",&a[i]);
26     for(int i=n;i>=1;i--)
27         rmax[i] = max(a[i],rmax[i+1]);
28     for(int i=1;i<=n;i++)
29     {
30         while(!sk.empty()&&sk.top()>=rmax[i])
31         {
32             vt.push_back(sk.top());
33             sk.pop();
34         }
35         sk.push(a[i]);
36     }
37     while(!sk.empty())
38     {
39         vt.push_back(sk.top());
40         sk.pop();
41     }
42     for(int i=0;i<vt.size();i++)
43         printf(i==vt.size()-1? "%d\n":"%d ",vt[i]);
44     
45     return 0;
46 }

 

把第一次wa的思路和代碼粘下:

 1 #include <bits/stdc++.h>
 2 typedef long long LL;
 3 #define pb push_back
 4 #define mst(a) memset(a,0,sizeof(a))
 5 const int INF = 0x3f3f3f3f;
 6 const double eps = 1e-8;
 7 const int mod = 1e9+7;
 8 const int maxn = 1e5+10;
 9 using namespace std;
10 
11 stack<int> sk;
12 vector<int> vt;
13 
14 int main()
15 {
16     #ifdef DEBUG
17     freopen("sample.txt","r",stdin); //freopen("data.out", "w", stdout);
18     #endif
19     
20     int n;
21     scanf("%d",&n);
22     int MAX=n;
23     for(int i=1;i<=n;i++)
24     {
25         int x;
26         scanf("%d",&x);
27         if(x!=MAX)
28         {
29             sk.push(x);
30             continue;
31         }
32         vt.push_back(x);
33         MAX--;
34         while(!sk.empty()&&sk.top()==MAX)
35         {
36             vt.push_back(sk.top());
37             sk.pop();
38             MAX--;
39         }
40     }
41     while(!sk.empty())
42     {
43         vt.push_back(sk.top());
44         sk.pop();
45     }
46     for(int i=0;i<vt.size();i++)
47         printf(i==vt.size()-1? "%d\n":"%d ",vt[i]);
48     
49     return 0;
50 }

這種做法hack數據:

5

1 4 3 5 2

正確答案:5 3 4 2 1,上述輸出:5 2 3 4 1

 

 

 

 

-


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM