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 }