栈的妙用

今天听了岛娘在牛客网的直播课以后,渐渐领悟到栈的一些妙用,下面通过几个进阶的题目来说明一下栈的妙用

阶段一:(Google Code Jam 2016 Round 3)

链接:https://code.google.com/codejam/contest/3224486/dashboard

分析:用栈进行匹配如果当前元素和栈顶元素相同,则栈顶出栈,同时加10分,否则入栈,最后分数在加上栈中元素个数/2*5 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 #include<vector>
 7 #include<algorithm>
 8 #include<stack>
 9 #include<set>
10 #include<queue>
11 using namespace std;
12 int main()
13 {
14     int T;
15     freopen("in.txt","r",stdin);
16     freopen("out.txt","w",stdout);
17     cin>>T;
18     for(int i=1;i<=T;i++){
19         string str;
20         cin>>str;
21         int len=str.length();
22         int ans=0;
23         stack<char> s;
24         s.push(' ');
25         for(int j=0;j<len;j++){
26             if(s.top()==str[j]){
27                 ans+=10;
28                 s.pop();
29             }else{
30                 s.push(str[j]);
31             }
32         }
33         ans+=s.size()/2*5;
34         printf("Case #%d: %d
",i,ans);
35     }
36 }
View Code

 阶段二:(POJ2559)

链接:http://poj.org/problem?id=2559

题意:求出矩形的最大面积

分析:这题我们可以用栈来进行维护,从而在O(N)的时间内解决。首先分析,对于某一个块,若它的高度比它前面的一个块小,则我们可以往左寻找,一直找到高度小于它的,这样就可以得到它的最大宽度是多少,同时对于比它高的部分,我们则可以去掉,这样下去,我们可以得到每一个块所能围城的最大面积,取其最大即为所求。我们用栈可以维护上述过程。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 #include<vector>
 7 #include<cctype>
 8 #include<algorithm>
 9 #include<stack>
10 #include<queue>
11 #include<map>
12 #include<set>
13 using namespace std;
14 const int maxn=100000+10;
15 int h[maxn];
16 int n;
17 int main()
18 {
19     while(cin>>n)
20     {
21         if(n==0)  break;
22         for(int i=1;i<=n;i++){
23             scanf("%d",&h[i]);
24         }
25         stack<int> s;
26         s.push(0); h[++n]=0;
27         long long ans=0;
28         for(int i=1;i<=n;i++)
29         {
30             while(h[i]<h[s.top()]){
31                 long long a=h[s.top()]; s.pop();
32                 long long b=i-s.top()-1;
33                 ans=max(ans,a*b);
34             }
35             s.push(i);
36         }
37         cout<<ans<<endl;
38     }
39 }
View Code

 阶段三:(POJ3494)

链接:http://poj.org/problem?id=3494

题意:求出全是1的最大矩阵的面积

分析:这题就是上一题的二维版本,我们可以将其转化为上一题的情形进行解答。我们可以以每一行作为基线,来统计其上由1组成的柱条的高度,若遇到0则h[j]置0,遇到1则h[j]+1,这样,我们就转化为求矩形的最大面积了,也就转化成了上一题。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 #include<vector>
 7 #include<cctype>
 8 #include<algorithm>
 9 #include<set>
10 #include<map>
11 #include<stack>
12 #include<queue>
13 using namespace std;
14 const int maxn=2000+10;
15 int a[maxn][maxn];
16 int h[maxn];
17 int m,n;
18 int main()
19 {
20     while(cin>>m>>n)
21     {
22         for(int i=1;i<=m;i++){
23             for(int j=1;j<=n;j++){
24                 scanf("%d",&a[i][j]);
25             }
26         }
27         memset(h,0,sizeof(h));
28         int ans=0;
29         for(int i=1;i<=m;i++){
30             for(int j=1;j<=n;j++){
31                 if(a[i][j]==0)
32                     h[j]=0;
33                 else
34                     ++h[j];
35             }
36             stack<int> s;
37             s.push(0); h[++n]=0;
38             for(int j=1;j<=n;j++){
39                 while(h[j]<h[s.top()]){
40                     int a=h[s.top()]; s.pop();
41                     int b=j-s.top()-1;
42                     ans=max(ans,a*b);
43                 }
44                 s.push(j);
45             }
46             --n;
47         }
48         cout<<ans<<endl;
49     }
50     return 0;
51 }
View Code
原文地址:https://www.cnblogs.com/wolf940509/p/6286189.html