Purple Book Example 8-19 UVa 12265 (Scanning Method + Monotone Stack)

First, a height array can be processed by the scanning method to store the maximum length that each grid can extend upwards from the current row.

This "extended" problem uses the scanning method, because often the current value can be updated with the previous result at this time


Then the key to this problem is to maintain a monotonic stack, and the top element of the stack is the answer required by the current state.

The properties satisfied by this monotone stack are: c increases from small to large, h increases from small to large, and hc increases from small to large. c represents the current column, h represents height[c]

Because the traversal is from left to right, c is always increasing, and then there is a while loop when joining, to ensure that h is always increasing,

The if that is added at the end is that the maintenance hc is always increasing.


This question is very similar to the one on the line of defense, in that it maintains a double-ordered structure, and the value of the structure needs to be modified when adding new elements. It's just that the question is two points, and this question is a monotonic stack.


#include<cstdio>
#include<cstring>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;

const int MAXN = 1123;
char s[MAXN][MAXN];
int height[MAXN], ans[MAXN<<1], n, m, top;

struct node
{
	int c, h;
	int val() { return h - c; }
	node(int c = 0, int h = 0) : c(c), h(h) {}
}stack[MAXN];

intmain()
{
	int T;
	scanf("%d", &T);
	
	while(T--)
	{
		scanf("%d%d", &n, &m);
		REP(i, 0, n) scanf("%s", s[i]);
		
		memset(height, 0, sizeof(height));
		memset(ans, 0, sizeof(ans));
		
		REP(i, 0, n)
		{
			top = -1;
			REP(j, 0, m)
			{
				if(s[i][j] == '#')
				{
					top = -1;
					height[j] = 0;
					continue;
				}
				
				height[j]++;
				node r(j, height[j]);
				if(top < 0)  stack[++top] = r;     
				else
				{
					while(top >= 0 && r.h <= stack[top].h) r.c = stack[top--].c;
					if(top < 0 || r.val() > stack[top].val()) stack[++top] = r;
				}

				ans[j+stack[top].val()+1]++;
			}
		}
		
		REP(i, 1, n + m + 1)
			if(ans[i])
				printf("%d x %d\n", ans[i], i * 2);
	}
	
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325949951&siteId=291194637