zoukankan      html  css  js  c++  java
  • UVa 12265

    链接:

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3417

    题意:

    输入一个n*m(1≤n,m≤1000)矩阵,每个格子可能是空地,也可能是沼泽。对于每个空地格子,
    求出以它为右下角的空地矩形的最大周长,然后统计每个周长出现了多少次。

    分析:

    扫描法 + 单调栈。
    按照从上到下的顺序处理每一行,在每一行中从左到右处理每个格子(以下称为“当前格”),
    找出以该格子为右下角的最大周长矩形(以下简称最优矩形)。只要找到了以每个
    格子为右下角的最优矩形,本题就可以得到解决。
    假定“当前格”已经固定,则只需要再确定一个左上角,就可以得到一个矩形。
    下面用c表示第c列,h表示第c列的空地高度。


    首先从上到下枚举“当前行”,然后从左到右枚举“当前列”。
    在移动“当前列”的过程中,保存若干个(c,h),按照c从小到大排列成有序表,
    则h也是从小到大排列,并且h-c也是从小到大排列。则可以在O(1)时间
    内求出每个当前格对应的最优矩形(因为最后一个矩形就是最优的),然后根据需要从右到
    左删除一些矩形(也可能不删除),并且可能会把最右边的矩形变矮。然后,当且仅当新矩
    形的h-c比它左边的矩形大时,加到表的最右边。由于添加和删除都在表的最右端,用一个
    栈来实现即可。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 const int UP = 1000 + 5;
     5 
     6 struct NODE {
     7     int c, h;
     8 } K[UP]; //
     9 
    10 int hei[UP], ans[UP*2];
    11 char s[UP][UP];
    12 
    13 int main(){
    14     int T, n, m;
    15     scanf("%d", &T);
    16     while(T--){
    17         scanf("%d%d", &n, &m);
    18         for(int i = 0; i < n; i++) scanf("%s", s[i]);
    19 
    20         memset(hei, 0, sizeof(hei));
    21         memset(ans, 0, sizeof(ans));
    22         for(int r = 0; r < n; r++){
    23             int p = 0; //栈顶指针
    24             for(int c = 0; c < m; c++){
    25                 if(s[r][c] == '#') p = hei[c] = 0;
    26                 else{
    27                     hei[c]++;
    28                     NODE nd = (NODE){c, hei[c]};
    29                     if(!p) K[++p] = nd;
    30                     else{
    31                         while(p && nd.h <= K[p].h) nd.c = K[p--].c;
    32                         if(!p || nd.h - nd.c > K[p].h - K[p].c) K[++p] = nd;
    33                     }
    34                     ans[K[p].h + c - K[p].c + 1]++;
    35                 }
    36             }
    37         }
    38 
    39         for(int i = 2; i <= m + n; i++) if(ans[i]){
    40             printf("%d x %d
    ", ans[i], i * 2);
    41         }
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    hortonworks
    使用Ambari快速部署Hadoop大数据环境
    js模板引擎
    Scala中的语言特性是如何实现的2
    IOS多线程编程一:概述
    Struts框架
    总体设计
    算法介绍
    社区与关怀
    从C#的Singleton设计模式
  • 原文地址:https://www.cnblogs.com/hkxy125/p/8321628.html
Copyright © 2011-2022 走看看