链接:https://nanti.jisuanke.com/t/42391
题意:求两个矩阵的最大重叠面积
题解:单调栈(悬线法...(有些没看懂))
对于第二个矩阵的每一个位置求 表示第
位置可以和第一个矩阵相同可以到达的最高高度.
下来转换成对于每行的 求直方图的最大面积
如下:
int LargestRectangleArea(vector<int>& height){
height.push_back(0);//为了统计,数组最后添加0,确保原数组的最后一位得到计算
stack<int> s;
int LargestArea = 0;
int temp,i=0;
while(i<(int)height.size()){
if(s.empty()||(height[i]>height[s.top()])){
s.push(i);
i++;
}
else{
temp = s.top();
s.pop();
LargestArea = max(LargestArea,height[temp]*(s.empty()?i:i-s.top()-1));
}
}
return LargestArea;
}
单调栈解决#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3 + 7;
int a[maxn][maxn],b[maxn][maxn];
int h[maxn][maxn];
int ans;
int n,m;
struct Node
{
int x,y;
}mp1[maxn * maxn + 100],mp2[maxn * maxn + 100];
struct STK
{
int l;
int h,i;
}stk[maxn];
void solve(int j)//递增单调栈
{
int top = 0;
stk[top].h = 0;stk[top].i = 0;
mp2[0].x = INF;mp2[0].y = INF;
h[n + 1][j] = 0;
int flag = 0;
for(int i = 0;i <= n + 1;i++)stk[i].l = 0;
for(int i = 1;i <= n + 1;i++)
{
if(mp1[b[i][j]].x == mp1[b[i - 1][j]].x + 1 && mp1[b[i][j]].y == mp1[b[i - 1][j]].y)
flag = 1;
else flag = 0;
int l = 0,len = 0;
while(top && (stk[top].h > h[i][j] || !flag))
{
int s = (stk[top].l + l + 1) * stk[top].h;
l += stk[top].l + 1;
ans = max(ans,s);
top--;
}
stk[++top].h = h[i][j];stk[top].i = i;
if(flag)stk[top].l = l;
else if(!flag)stk[top].l = 0;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
scanf("%d",&a[i][j]);
mp1[a[i][j]].x = i;
mp1[a[i][j]].y = j;
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
scanf("%d",&b[i][j]);
mp2[b[i][j]].x = i;mp2[b[i][j]].y = j;
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if(mp1[b[i][j]].x == mp1[b[i][j - 1]].x && mp1[b[i][j]].y == mp1[b[i][j - 1]].y + 1)
{
h[i][j] = h[i][j - 1] + 1;
}
else h[i][j] = 1;
}
}
for(int i = 1;i <= m;i++)
{
solve(i);
}
printf("%d\n",ans);
return 0;
}

京公网安备 11010502036488号