uva 1330 - City Game

题目链接:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=460&page=show_problem&problem=4076


以前做过一道一维的,这题只是变成了二维的,其他方法都一样。HDU 1506  Largest Rectangle in a Histogram   题解



代码1:

#include<cstdio>
#include<cstring>
#include<stack>
using std::stack;

const int MAXN = 1010;
char str[MAXN*3];
int sum[MAXN][MAXN];
int left[MAXN], right[MAXN];
int n, m;

inline void input(){
    scanf("%d%d%*c", &n, &m);
    for(int i=1; i<=n; ++i){
        for(int j=1; j<=m; ++j){
            char ch = getchar();
            while(ch!='F' && ch!='R') ch=getchar();
            sum[i][j] = ch=='R'?0:1;
            if(sum[i][j]) sum[i][j] += sum[i-1][j];
        }
    } 
}

inline void solve(){
    input(); 
    int ans = 0;
    for(int i=1; i<=n; ++i){
        sum[i][0] = sum[i][m+1] = -1;
        for(int j=1; j<=m; ++j) 
            left[j]=right[j]=j;
        for(int j=1; j<=m; ++j){
            while(sum[i][j] <= sum[i][left[j]-1])
                left[j] = left[left[j]-1];
        }
        for(int j=m; j>=1; --j){
            while(sum[i][j] <= sum[i][right[j]+1])
                right[j] = right[right[j]+1];
            int tmp = (right[j]-left[j]+1)*sum[i][j];
            if(tmp > ans) ans=tmp;
        }
    }
    printf("%d\n", ans*3);
}

int main(){
    int nCase;
    scanf("%d", &nCase);
    while(nCase--){
        
       solve();
    }
    return 0;
} 



代码2(栈扫描):

#include<cstdio>
#include<cstring>
#include<stack>
using std::stack;

const int MAXN = 1010;
char str[MAXN*3];
int sum[MAXN][MAXN];
int n, m;

inline void input(){
    scanf("%d%d%*c", &n, &m);
    memset(sum, 0, sizeof(sum));
    for(int i=1; i<=n; ++i){
        for(int j=1; j<=m; ++j){
            char ch = getchar();
            while(ch!='F' && ch!='R') ch=getchar();
            sum[i][j] = ch=='R'?0:1;
            if(sum[i][j]) sum[i][j] += sum[i-1][j];
        }
    } 
}

inline void solve(){
    input(); 
    int ans = 0;
    for(int i=1; i<=n; ++i){
        sum[i][0] = sum[i][m+1] = -1;
        stack<int>q;
        for(int j=1; j<=m+1; ++j){
            if(q.empty() || sum[i][j]>sum[i][q.top()]){
                q.push(j);
            }
            else if(sum[i][j] < sum[i][q.top()]){
                int pos;
                while(!q.empty() && sum[i][q.top()]>sum[i][j]){
                    int tmp = (j-q.top())*sum[i][q.top()];
                    if(tmp > ans)
                        ans = tmp;
                    pos = q.top();
                    q.pop();
                }
                q.push(pos);
                sum[i][pos] = sum[i][j];
            }
        }
    }
    printf("%d\n", ans*3);
}

int main(){
    int nCase;
    scanf("%d", &nCase);
    while(nCase--){
        
       solve();
    }
    return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值