zoukankan      html  css  js  c++  java
  • 刷题总结——玉蟾宫(bzoj3039单调栈)

    题目:

    Description

    有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。
    这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。
    现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着'F'并且面积最大。
    但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们每人给你S两银子。

    Input

    第一行两个整数N,M,表示矩形土地有N行M列。
    接下来N行,每行M个用空格隔开的字符'F'或'R',描述了矩形土地。

    Output

    输出一个整数,表示你能得到多少银子,即(3*最大'F'矩形土地面积)的值。

    Sample Input

    5 6
    R F F F F F
    F F F F F F
    R R R F F F
    F F F F F F
    F F F F F F

    Sample Output

    45

    HINT



    对于50%的数据,1<=N,M<=200

    对于100%的数据,1<=N,M<=1000

    Source

    题解:

      首先枚举每一行,再枚举每一列算向上的最大高度····

      至于宽度利用从左到右,从右到左两次单调栈枚举第一次小于该列高度的列的位置x,则x+1(x-1)要么是这一列,要么是第一个大于这一列的列(且x+1(x-1)到枚举的列的高度都大于等与枚举的这一列),从而算出矩形的最大值

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int N=1005;
    int map[N][N],stack[N],tail,n,m,height[N],Left[N],Right[N],ans=0;
    char c;
    int main()
    {
     // freopen("a.in","r",stdin);
      scanf("%d%d",&n,&m);
      for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
          c=getchar();
          while(c!='F'&&c!='R')  c=getchar();
          if(c=='F')  map[i][j]=1;
        }
      for(int i=1;i<=n;i++)
      { 
        for(int j=1;j<=m;j++)
        {
          if(map[i][j])  height[j]++;
          else height[j]=0;
        }
        tail=0;
        stack[0]=0;
        for(int j=1;j<=m;j++)
        {
          while(height[stack[tail]]>=height[j]&&tail)  tail--;
          Left[j]=stack[tail]+1;
          stack[++tail]=j;
        }
        tail=0;
        stack[0]=m+1;
        for(int j=m;j>=1;j--)
        {
          while(height[stack[tail]]>=height[j]&&tail)  tail--;
          Right[j]=stack[tail]-1;
          stack[++tail]=j;
        }
        for(int j=1;j<=m;j++)  ans=max(ans,height[j]*(Right[j]-Left[j]+1));
      }
      cout<<ans*3<<endl;
      return 0;
    }
  • 相关阅读:
    Linux Core Dump
    ODP.NET Managed正式推出
    获取EditText的光标位置
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
  • 原文地址:https://www.cnblogs.com/AseanA/p/7517341.html
Copyright © 2011-2022 走看看