题目大意
求最大子矩形
解题思路
参考2003年王知昆论文
首先将四个点也加入到障碍点之中,然后将所有的障碍点按照x坐标排序。
由于最大子矩形的边不是与整个区域的边重合就是就是紧紧挨着障碍点,那么我们从左往右枚举左边界,然后枚举右边界,不断修改上下边界,得到的每一个矩形一定包括最大子矩形,上下边界的修改方法就是一点点地从区域上下边界缩小到枚举到的障碍点即可。
AC代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 5050;
struct node{
int x, y;
bool operator < (const node &rhs)const{
return rhs.x < x;
}
};
node s[maxn];
int w, l, n;
int main(){
scanf("%d%d", &l, &w);
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d%d", &s[i].x, &s[i].y);
s[n++] = (node){0, 0}; s[n++] = (node){w, 0};
s[n++] = (node){0, l}; s[n++] = (node){w, l};
sort(s, s + n);
int left, right, up, down;
int ans = 0;
for (int i = 0; i < n; i++){
left = s[i].x; up = 0; down = l;
for (int j = i + 1; j < n; j++){
if (s[j].x == left) continue;
right = s[j].x;
int ss = abs((right - left) * (down - up));
ans = max(ans, ss);
if (s[j].y < down && s[j].y >= s[i].y){down = s[j].y;}
if (s[j].y > up && s[j].y <= s[i].y){up = s[j].y;}
if (up >= down) break;
}
}
printf("%d\n", ans);
return 0;
}