!-- Loading 底层遮罩 -->

P1578 奶牛浴场

传送门

思路

障碍点法:通过枚举所有的极大子矩形找出最大子矩形 。最大矩形必然以障碍点为边界,枚举障碍点计算最大子矩形并在每次计算后更新上下边界。需要将地图的四个边界加入计算并分别从横坐标,纵坐标枚举最大矩形防止漏算。

代码

#include<iostream>
#include<algorithm>
#define MAXN 5007
using namespace std;
int L, W, n, cnt, ans;
struct Node { int x, y; }obs[MAXN];
bool cmp1(Node A, Node B) {
    if (A.x != B.x) return A.x < B.x;
    else return A.y < A.y;
}
bool cmp2(Node A, Node B) {
    if (A.y != B.y) return A.y < B.y;
    else return A.x < A.x;
}
int main(void)
{
    cin >> L >> W >> n;
    obs[++cnt].x = 0, obs[cnt].y = 0;
    obs[++cnt].x = L, obs[cnt].y = 0;
    obs[++cnt].x = 0, obs[cnt].y = W;
    obs[++cnt].x = L, obs[cnt].y = W;
    for (int i = 1; i <= n; i++)
        cin >> obs[++cnt].x >> obs[cnt].y;
    sort(obs + 1, obs + n + 5, cmp1);
    for (int i = 1; i <= cnt; i++)
    {
        int base = 0, top = W;
        for (int j = i + 1; j <= cnt; j++)
        {
            ans = max(ans, (top - base) * (obs[j].x - obs[i].x));
            if (obs[j].y >= obs[i].y) top = min(top, obs[j].y);
            else base = max(base, obs[j].y);
            if (base >= top) break;
        }
    }
    sort(obs + 1, obs + n + 5, cmp2);
    for (int i = 1; i <= cnt; i++)
    {
        int base = L, top = 0;
        for (int j = i + 1; j <= cnt; j++)
        {
            ans = max(ans, (base - top) * (obs[j].y - obs[i].y));
            if (obs[j].x >= obs[i].x) base = min(base, obs[j].x);
            else top = max(top, obs[j].x);
            if (top >= base) break;
        }
    }
    cout << ans;
    return 0;
}
 

 

posted @ 2022-03-30 21:05  Thinker-X  阅读(33)  评论(0)    收藏  举报