直方图的最大矩形面积
poj 2559
高度保持单调增,弹出时向最右看。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+10;
int n;
int h[maxn];
struct Node{
int idx, h;
};
stack<Node> s;
int main(){
ios::sync_with_stdio(false);
while(~scanf("%d", &n)&&n){
ll ans = 0;
for(int i=0; i<n; i++) scanf("%d", &h[i]);
h[n] = 0;
for(int i=0; i<=n; i++){
if(s.empty()) s.push(Node{i, h[i]});
else if(h[i]>s.top().h){
s.push(Node{i, h[i]});
}
else if(h[i]<s.top().h){
int target = i;
while(!s.empty()&&h[i]<=s.top().h){
ans = max(ans, 1ll*(i-s.top().idx)*s.top().h);
target = s.top().idx;
s.pop();
}
s.push(Node{target, h[i]});
}
}
printf("%lld
", ans);
}
return 0;
}
n*m矩阵空地周长
水坑的最大储水量
一维
- 给h:扫两遍
- 给地面的高和天花板的高:扫两遍
- 地面是一个三角形的斜坡:用栈
二维
- 仅给地面的高
NYOJ 547
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
typedef long long ll;
ll a[310][310];
bool vis[310][310];
int n, m;
int dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 };
struct node{
int x, y, v;
bool operator < (const node & oth)const
{
return v > oth.v; // 每一层都按从小到大的值排
}
};
priority_queue<node>pq;
void bfs()
{
ll ans = 0;
while (!pq.empty())
{
int x = pq.top().x, y = pq.top().y, v = pq.top().v;
pq.pop();
if (vis[x][y])
continue;
vis[x][y] = 1;
for (int i = 0; i < 4; i++)
{
int xx = x + dir[i][0];
int yy = y + dir[i][1];
int vv = a[xx][yy];
if (xx < n && xx > 1 && yy < m && yy > 1 && !vis[xx][yy])
{
if (vv < v) //若该点小于当前点,则可升高
{
ans += v - vv;
a[xx][yy] = v; //更新信息
}
pq.push({ xx, yy, a[xx][yy] });
}
}
}
cout << ans << endl;
}
int main(){
while (cin >> m >> n)
{
memset(vis, 0, sizeof vis);
while (!pq.empty())
pq.pop();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
if (i == 1 || j == 1 || i == n || j == m)
pq.push({ i, j, a[i][j] }); //先压入边界的点
}
bfs();
/*for (int i = 1; i <= n; i++, cout << endl)
for (int j = 1; j <= m; j++)
cout << a[i][j] << " ";*/
}
return 0;
}