今天听了岛娘在牛客网的直播课以后,渐渐领悟到栈的一些妙用,下面通过几个进阶的题目来说明一下栈的妙用
阶段一:(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 }
阶段二:(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 }
阶段三:(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 }