City Game UVA - 1330 单调栈

问题

https://vjudge.net/problem/UVA-1330

分析

单调栈的使用,依此遍历每一行,同时每一行开始维护两个单调栈,确定以一个格子的对应列的高度构建矩形,向左边和右边可以扩展的最大范围,也就是宽度

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
typedef long long LL;
const int maxn=1000+5;
int m,n,kase=0,num[maxn],s[maxn],p,L[maxn],R[maxn];
char g[maxn][maxn],ch;
int main(void){
    scanf("%d",&kase);
    while(kase--){
        int ans=0;
        scanf("%d%d",&m,&n);
        for(int i=0;i<m;++i){
            for(int j=0;j<n;++j){
                while((ch=getchar()) && ch!='F' && ch!='R');
                g[i][j]=ch;
            }
        }
        memset(num,0,sizeof(num));
        for(int i=0;i<m;++i){
            //计算每列中上面累积的连续的F的数量
            for(int j=0;j<n;++j){
                if(g[i][j]=='F') ++num[j];
                else num[j]=0;
            }
            p=0;  //清空栈,然后记录L和R的结果在数组中(确定高度后,左边,右边的最大宽度)
            //高度是num[j],先计算左边的
            for(int j=0;j<n;++j){
                while(p>0 && num[s[p]]>=num[j]) --p;
                if(p==0) L[j]=0;
                else L[j]=s[p]+1;
                s[++p]=j;
            }
            //计算右边,栈中只记录编号
            p=0;
            for(int j=n-1;j>=0;--j){
                while(p>0 && num[s[p]]>=num[j]) --p;
                if(p==0) R[j]=n-1;
                else R[j]=s[p]-1;
                s[++p]=j;
            }
            for(int j=0;j<n;++j)
                ans=max(ans,num[j]*(R[j]-L[j]+1));
        }
        printf("%d\n",ans*3);
    }
    return 0;
}
发布了180 篇原创文章 · 获赞 3 · 访问量 3478

猜你喜欢

转载自blog.csdn.net/zpf1998/article/details/104716188
今日推荐