首页 > 代码库 > BZOJ1069 [SCOI2007]最大土地面积

BZOJ1069 [SCOI2007]最大土地面积

终于做出来了2333~~~~

凸包+旋转卡(qia)壳。

n = 2000,所以可以先枚举两个点作为对角线上的点。

然后由于决策单调性,另外的两个点可以o(1)求出,所以就做好了额。

计算几何太烦太烦>.<

 

 1 /************************************************************** 2     Problem: 1069 3     User: rausen 4     Language: C++ 5     Result: Accepted 6     Time:148 ms 7     Memory:872 kb 8 ****************************************************************/ 9  10 #include <cstdio>11 #include <algorithm>12  13 #define points P14 using namespace std;15 typedef double lf;16 const int N = 2005;17 struct points{18     lf x, y;19 }p[N], s[N];20 int n, top;21  22  23 inline lf operator * (const P a, const P b){24     return a.x * b.y - a.y * b.x;25 }26  27 inline P operator - (const P a, const P b){28     P tmp;29     tmp.x = a.x - b.x, tmp.y = a.y - b.y;30     return tmp;31 }32  33 inline lf Sqr(const lf x){34     return x * x;35 }36  37 inline lf dis(const P a, const P b){38     return Sqr(a.x - b.x) + Sqr(a.y - b.y);39 }40  41 inline bool operator < (const P a, const P b){42     lf tmp = (a - p[1]) * (b - p[1]);43     return tmp == 0 ? dis(p[1], a) < dis(p[1], b) : tmp > 0;44 }45  46 inline lf Area(const int x, const int y, const int z){47     return (s[z] - s[x]) * (s[y] - s[x]);48 }49  50 int work(){51     int k = 1;52     for (int i = 2; i <= n; ++i)53         if (p[i].y == p[k].y ? p[i].x < p[k].x : p[i].y < p[k].y) k = i;54     swap(p[1], p[k]);55     sort(p + 2, p + n + 1);56     top = 2, s[1] = p[1], s[2] = p[2];57     for (int i = 3; i <= n; ++i){58         while ((s[top] - s[top - 1]) * (p[i] - s[top]) <= 0) --top;59         s[++top] = p[i];60     }61 }62  63 double Calc(){64     s[top + 1] = p[1];65     lf res = 0;66     int a, b, x, y;67     for (x = 1; x <= top; ++x){68         a = x % top + 1, b = (x + 2) % top + 1;69         for (y = x + 2; y <= top; ++y){70             while (a % top + 1 != y && Area(x, y, a + 1) > Area(x, y, a))71                 a = a % top + 1;72             while (b % top + 1 != x && Area(x, b + 1, y) > Area(x, b, y))73                 b = b % top + 1;74             res = max(Area(x, y, a) + Area(x, b, y), res);75         }76     }77     return res;78 }79  80 int main(){81     scanf("%d\n", &n);82     for (int i = 1; i <= n; ++i)83         scanf("%lf%lf", &p[i].x, &p[i].y);84     work();85     printf("%.3lf\n", Calc() / 2);86     return 0;87 }
View Code

 

BZOJ1069 [SCOI2007]最大土地面积