BZOJ 1132 Tro

Tro

【问题描述】

平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和 N<=3000

【输入格式】

第一行给出数字N,N在[3,3000] 下面N行给出N个点的坐标,其值在[0,10000]

【输出格式】

保留一位小数,误差不超过0.1

【样例输入】

5
0 0
1 2
0 2
1 0
1 1

【样例输出】

7.0


题解:

叉积之和

我们以每个点为原点,维护前缀和

为了保证夹角不超过π,先按水平序排序

为了保证面积都是正值,按极角序排序

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 using namespace std;
 8 struct point
 9 {
10     long long x, y;
11     friend inline long long operator * (point a, point b)
12     {
13         return a.x * b.y - a.y * b.x;
14     }
15     friend inline point operator - (point a, point b)
16     {
17         return (point) {a.x - b.x, a.y - b.y};
18     }
19     inline void empty()
20     {
21         x = y = 0;
22     }
23 };
24 point operator + (point a, point b)
25 {
26     point c;
27     c.x = a.x + b.x;
28     c.y = b.y + b.y;
29     return c;
30 }
31 const int maxn = 3333;
32 int n;
33 point p[maxn];
34 inline bool lev(point a, point b)
35 {
36     if(a.y != b.y) return a.y < b.y;
37     return a.x < b.x;
38 }
39 
40 int num;
41 point np[maxn];
42 inline bool ang(point a, point b)
43 {
44     return a * b > 0;
45 }
46 point sum;
47 long long ans;
48 int main()
49 {
50     scanf("%d", &n);
51     for(int i = 1; i <= n; ++i) scanf("%lld %lld", &p[i].x, &p[i].y);
52     sort(p + 1, p + 1 + n, lev);
53     for(int k = 1; k <= n; ++k)
54     {
55         num = 0;
56         for(int i = k + 1; i <= n; ++i) np[++num] = p[i] - p[k];
57         sort(np + 1, np + 1 + num, ang);
58         sum.empty();
59         for(int i = 1; i <= num; ++i)
60         {
61             ans += sum * np[i];
62             sum.x += np[i].x;
63             sum.y += np[i].y;
64         }
65     }
66     printf("%lld.%d", ans >> 1, (ans & 1) ? 5 : 0);
67 }
posted @ 2017-05-24 16:35  草根柴鸡  阅读(216)  评论(1编辑  收藏  举报