zoukankan      html  css  js  c++  java
  • [Nescafé 20] 玉蟾宫

    ★   输入文件:jademoon.in   输出文件:jademoon.out   简单对比
    时间限制:1 s   内存限制:128 MB

    【背景】

    有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。

    【题目描述】

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

    【输入格式】

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

    【输出格式】

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

    【样例输入】

    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
    

    【样例输出】

    45

    【提示】

    各个测试点1s

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

    【来源】

    http://www.tyvj.cn/Problem_Show.aspx?id=1939

    思路

    表解在这,我就不说话了;

    官方题解:

    们先来考虑这样一个问题,水平线上有一些宽度为1,高度不定的阴影区域,要求找到包含在这个区域内的一个矩形,使得矩形面积最大。

    如图所示,高度不一的柱形条就是阴影区域,不同颜色框出的矩形都满足要求,其中红色矩形的面积最大。

     

    维护一个栈中元素高度单调递增的栈,初始化栈中第一个元素高度宽度均为0。

    然后每次读入一个矩形,若它比栈顶元素还高就直接进栈;

    否则不断将栈中元素弹栈,直到当前栈顶元素能够与读入的矩形满足高度递增。

    弹栈过程中累加弹出的元素的宽度,然后每弹出一个就判断(当前弹出元素的高度×累加的宽度)能否更新最大面积ans。

    然后以新的矩形高度作高,刚才弹出栈的元素总宽度加上新矩形宽度作宽,把这个矩形插入到栈里。

    最终栈肯定是一个单调的,只需要再把栈一个个弹空,弹栈过程中仍像上面那样计算即可。

    这个算法的时间复杂度是O(n)的。

    在本题中,我们只需要枚举每一行以上的'F'作为阴影区域,用上述单调栈算法求一遍最大矩形面积即可。时间复杂度O(NM)。

    代码实现

     1 #include<cstdio>
     2 const int maxn=1e3+10;
     3 inline int max_(int x,int y){return x>y?x:y;}
     4 int n,m,ans;
     5 int map[maxn][maxn];
     6 char ch[3];
     7 int q[maxn],s[maxn],top;
     8 void do_stack(int k){
     9     q[top=1]=map[k][1],s[top]=1;
    10     for(int i=2;i<=m+1;i++){
    11         int j=0;
    12         while(map[k][i]<q[top]){
    13             j+=s[top];
    14             ans=max_(ans,q[top--]*j);
    15         }
    16         q[++top]=map[k][i],s[top]=j+1;
    17     }
    18 }
    19 int main(){
    20     freopen("jademoon.in","r",stdin);
    21     freopen("jademoon.out","w",stdout);
    22     scanf("%d%d",&n,&m);
    23     for(int i=1;i<=n;i++)
    24     for(int j=1;j<=m;j++){
    25         scanf("%s",ch);
    26         if(ch[0]=='F') map[i][j]=map[i-1][j]+1; 
    27     }
    28     for(int i=1;i<=n;i++){
    29         do_stack(i);
    30     }
    31     printf("%d
    ",ans*3);
    32     return 0;
    33 }
  • 相关阅读:
    计算机与软件工程 作业一
    软件工程作业6 咸鱼不闲团队 校园二手交易系统
    软件工程 作业5
    计算与软件工程 作业4
    软件工程第四次作业评价总结
    计算与软件工程 作业3
    计算与软件共程作业2
    计算与软件工程 作业一
    计算与软件工程作业六
    计算与软件工程作业五
  • 原文地址:https://www.cnblogs.com/J-william/p/7419800.html
Copyright © 2011-2022 走看看