UVa 12265:Selling Land(单调栈)

来源:互联网 发布:centos iscsi target 编辑:程序博客网 时间:2024/05/18 22:41

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=844&page=show_problem&problem=3417

题意:输入一个nm(1n,m1000)矩阵,每个格子可能是空地,也可能是沼泽。对于每个空地格子,求出以它为右下角的空矩形的最大周长,然后统计每个周长出现了多少次。下图中标注了3个位置的最大空矩形,其周长分别是6,10,12.如果统计完所有20个空地,答案是6*4(表示周长为4的矩形有6个)、5*6、3*10、1*12。(本段摘自《算法竞赛入门经典(第2版)》)

分析:
       分析详见《算法竞赛入门经典(第2版)》。在组织单调栈时要注意并非所有元素都要入栈,栈顶元素始终保持为当前最优即可。

代码:

#include <fstream>#include <iostream>#include <cstring>#include <algorithm>#include <stack>#include <sstream>#include <string>#include <map>#include <cmath>#include <queue>#include <vector>#include <set>#include <string>#include <vector>using namespace std;const int maxn = 1000 + 5;int T, n, m, tmp, l;int h[maxn];char a[maxn][maxn];map< int, int > M;int main(){    scanf("%d", &T);    for (int C = 0; C < T; ++C)    {        M.clear();        memset(h, 0, sizeof(h));        scanf("%d%d", &n, &m);        for (int i = 1; i <= n; ++i)            scanf("%s", a[i] + 1);        for (int i = 1; i <= n; ++i)        {            for (int j = 1; j <= m; ++j)                if (a[i][j] == '.')                    ++h[j];                else                    h[j] = 0;            stack< pair<int, int> > sta;            for (int j = 1; j <= m; ++j)            {                if (h[j] > 0)                {                    pair< int, int > cur(j, h[j]);                    while (!sta.empty() && sta.top().second >= cur.second)                    {                        cur.first = sta.top().first;                        sta.pop();                    }                    if (sta.empty() || sta.top().second - sta.top().first < cur.second - cur.first)                        sta.push(cur);                    ++M[j - sta.top().first + 1 + sta.top().second];                }                else                    while (!sta.empty())                        sta.pop();            }        }        for (map< int, int >::iterator it = M.begin(); it != M.end(); ++it)            printf("%d x %d\n", it->second, it->first * 2);    }    return 0;}
0 0
原创粉丝点击