题目链接:https://vjudge.net/problem/UVA-12265
思路参见紫书第八章例题8-19题解
先进行一次预处理,保存每个位置向上延伸的最大高度,之后处理方便很多
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<string>
#include<stack>
using namespace std;
typedef long long ll;
const int N=1000+10;
struct node
{
int h,c;
node (int a,int b)
{
h=a;c=b;
}
};
char g[N][N];
int a[N][N];
int n,m;
int main()
{
//freopen("/home/zlwang/Desktop/t2.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%s",g[i]);
for(int j=0;j<m;j++)
{
int k=0;
for(int i=0;i<n;i++)
{
if(g[i][j]=='#') k=i+1;
a[i][j]=i-k+1;
}
}
set<int> s;
map<int,int> num;
for(int i=0;i<n;i++)
{
stack<node> b;
for(int j=0;j<m;j++)
{
int k=j;
while(!b.empty()&&a[i][j]<=b.top().h)
{
k=b.top().c;
b.pop();
}
if(!a[i][j]) continue;
if(b.empty()||a[i][j]-b.top().h>k-b.top().c)
{
b.push(node(a[i][j],k));
}
node c=b.top();
int x=2*(j-c.c+1+c.h);
s.insert(x);
num[x]++;
}
}
for(set<int>::iterator it=s.begin();it!=s.end();it++)
{
printf("%d x %d\n",num[*it],*it);
}
}
return 0;
}