您的位置:首页 > 其它

[BZOJ]1069 [SCOI2007] 最大土地面积 凸包 + 旋转卡壳

2017-12-05 15:59 561 查看

1069: [SCOI2007]最大土地面积

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 3720  Solved: 1471

[Submit][Status][Discuss]

Description

  在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成

的多边形面积最大。

Input

  第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。

Output

  最大的多边形面积,答案精确到小数点后3位。

Sample Input

5

0 0

1 0

1 1

0 1

0.5 0.5

Sample Output

1.000

HINT

数据范围 n<=2000, |x|,|y|<=100000

Source



[Submit][Status][Discuss]

HOME Back

  首先很显然四个点一定在凸包上, 其次... n只有两千? 暴力枚举对角线, 以对角线为底, 分别在两边找最大面积三角形. 很容易发现这是单调的, 像旋(xuan)转(zhuan)卡(qia)壳(ke)那样搞即可.

#include<bits/stdc++.h>
#define pp pop_back
#define pb push_back
using namespace std;
int n, m;
double ans;
struct Vector {
double x, y;
Vector() {}
Vector(double x, double y) : x(x), y(y) {}
inline friend bool operator < (const Vector &r, const Vector &s) {
return r.x < s.x || (r.x == s.x && r.y < s.y);
}
inline friend Vector operator - (const Vector &r, const Vector &s) {
return Vector(r.x - s.x, r.y - s.y);
}
};
typedef Vector Point;
vector<Point> pts, cvx;
inline double cross (const Vector &r, const Vector &s) {
return r.x * s.y - r.y * s.x;
}
inline double area(const Point &A, const Point &B, const Point &C) {
return cross(B - A, C - A);
}
inline void Convex_Hull() {
sort(pts.begin(), pts.end());
for (int i = 0; i < n; ++ i) {
while (m > 1 && area(cvx[m - 2], cvx[m - 1], pts[i]) >= 0) cvx.pp(), m --;
cvx.pb(pts[i]), m ++;
}
int k = m;
for (int i = n - 2; ~i; -- i) {
while (m > k && area(cvx[m - 2], cvx[m - 1], pts[i]) >= 0) cvx.pp(), m --;
cvx.pb(pts[i]), m ++;
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++ i) {
double x, y;
scanf("%lf%lf", &x, &y);
pts.pb(Point(x, y));
}
Convex_Hull();
for (int i = 0; i < m - 1; ++ i) {
int h = i + 1, t = i + 3;
for (int j = i + 2; j < m - 2; ++ j) {
while (h < j - 2 && area(cvx[i], cvx[j], cvx[h]) <= area(cvx[i], cvx[j], cvx[h + 1])) h ++;
while (t <= j || (t < m - 2 && area(cvx[i], cvx[t], cvx[j]) <= area(cvx[i], cvx[t + 1], cvx[j]))) t ++;
ans = max(ans, area(cvx[i], cvx[j], cvx[h]) + area(cvx[i], cvx[t], cvx[j]));
}
}
printf("%.3f\n", ans / 2);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: