POJ 2079 求最大三角形面积

来源:互联网 发布:网络入门书籍 编辑:程序博客网 时间:2024/05/17 05:16

题解 :

这个题目的关键之处在于你要发现这个一个凸包,然后许多东西在凸包上面就有了单调性,旋转卡壳就是用了这个道理才得以实现。
我们发现对于每一个 i j 来说 k 都是单调的这样我们就可以通过枚举i j 利用 k 的单调性 使得时间复杂度降到 n ^ 2 凸包的优美性质啊 单调性 然后就是旋转卡壳了

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const double eps = 1e-8;const int maxn = 50005;struct point {    double x,y;}p[maxn],tu[maxn];int n;double ab (double x) {return x > 0 ? x : -x;}int sgn (double x) {    if (ab (x) < eps) return 0;    return x > 0 ? 1 : -1;}point init;double cross (point a,point b,point c) {    return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);}double cross (double x1,double y1,double x2,double y2) {    return x1 * y2 - x2 * y1;}double dist (point a,point b) {    return sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}bool cmp (const point a,const point b) {    int sg = sgn (cross (a.x-init.x,a.y - init.y,b.x - init.x,b.y - init.y));    if (sg == 0) return dist (init,a) < dist (init,b);    return sg > 0;}int tot = 0;void tubao () {    for (int i = 1;i <= 2; ++ i) tu[i] = p[i];    tot = 2;    for (int i = 3;i <= n; ++ i) {        while (tot > 1) {            point p1,p2,p3;            p1 = tu[tot];            p2 = tu[tot - 1];            p3 = p[i];            if (cross(p1.x - p2.x,p1.y - p2.y,p3.x - p1.x,p3.y-p1.y) <= 0) tot --;            else break;        }        tu[++ tot] = p[i];    }}double solve () {    double ans = 0;    tu[tot + 1] = tu[1];    for (int i = 1;i <= tot; ++ i) {        int k = 2;        for (int j = i + 1;j <= tot; ++ j) {            while (ab(cross(tu[k], tu[i], tu[j])) < ab (cross(tu[k + 1],tu[i],tu[j]))) k = k % tot + 1;            double s = 0.5 * ab(cross(tu[k], tu[i], tu[j]));            ans = max (ans,s);        }    }    return ans;}int main () {    while (scanf ("%d",&n) && n != -1) {        for (int i = 1;i <= n; ++ i) {            scanf ("%lf%lf",&p[i].x,&p[i].y);            if (p[i].y < p[1].y || (p[i].y == p[1].y && p[i].x < p[1].x)) swap (p[i],p[1]);        }        init = p[1];        sort (p + 2,p + n + 1,cmp);        tubao();        printf ("%.2f\n",solve());    }    return 0;}
原创粉丝点击