【POJ 1964】求10图矩形最大面积

1 篇文章 0 订阅

星爷代码:

思想——维护左上角的单调栈

#include <iostream>
#include <stdio.h>
#include <cstring>

using namespace std;

int main(){
    int casenum;
    cin >> casenum;
    while (casenum--){
        int n, m, c;
        static int map[1010][1010];
        cin >> n >> m;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++)
                while (map[i][j] = getchar(), map[i][j] != 'F' && map[i][j] != 'R');
            map[i][m + 1] = 'R';
        }
        int ans = 0;
        int height[1010];
        memset(height, 0, sizeof(height));
        for (int i = 1; i <= n; i++) {
            int stack[1010][2], top = 0;
            for (int j = 1; j <= m + 1; j++) {
                if (map[i][j] == 'R') height[j] = 0;
                else height[j]++;
                stack[top][0] = j;
                while (top > 0 && stack[top - 1][1] >= height[j]) {
                    ans = max(ans, stack[top - 1][1] * (j - stack[top - 1][0]));
                    top--;
                }
                stack[top++][1] = height[j];
            }
        }
        cout << ans * 3 << endl;
    }
    return 0;
}


我的代码:

维护以i为高度的最远距离l,r

#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int NN=2000;
int pre[NN],stack[NN],stacknum,l[NN],r[NN],z;
bool xmap[NN][NN];
char tmp[10];
int T,n,m;
int main()
{
    scanf("%d",&T);
    while (T--)
    {
          scanf("%d%d",&n,&m);
          for (int i=1;i<=n;++i)
              for (int j=1;j<=m;++j)
              {
                  scanf("%s",&tmp);
                  if (strcmp(tmp,"R")==0) xmap[i][j]=0;
                  else xmap[i][j]=1;
              }
          memset(pre,0,sizeof(pre));
          int ans=0;
          for (int j=1;j<=m;++j)
          {
              for (int i=1;i<=n;++i)
                  if (xmap[i][j]) ++pre[i];
                  else pre[i]=0;
              memset(stack,0,sizeof(stack));
              memset(l,0,sizeof(l));
              memset(r,0,sizeof(r));
              l[0]=r[0]=l[n+1]=r[n+1]=-1;
              z=0;
              for (int i=1;i<=n;++i)
              {
                  while (z>0 && pre[stack[z-1]]>=pre[i]) --z;
                  l[i]=stack[z-1];
                  if (z==0) l[i]=0;
                  stack[z]=i;
                  ++z;
              }
              z=0;
              for(int i=n;i>=1;--i)
              {
                      while (z>0 && pre[stack[z-1]]>=pre[i]) --z;
                      r[i]=stack[z-1];
                      if (z==0) r[i]=n+1;
                      stack[z]=i;
                      ++z;
              }
              for (int i=1;i<=n;++i)
                  if (ans<(r[i]-l[i]-1) * pre[i])
                     ans=pre[i]*(r[i]-l[i]-1);
          }
          printf("%d\n",ans*3);
                 
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值