bzoj1132 [POI2008]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

枚举i,求出所有点与i形成的向量

对于向量的面积用叉积

$x_j*y_k-y_j*x_k$

如果假设i<j<k

为了保证算出来是整数,把向量按极角排序,这里不用atan2,而是用叉积

$\sum\limits_{j=i+1}^n(x_j*\sum\limits_{k=j+1}^ny_k-\sum\limits_{k=j+1}^nx_k*y_j)$

发现维护2个后缀和就行了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long lol;
 8 struct Point
 9 {
10    lol x,y;
11   Point(lol a=0,lol b=0) {x=a,y=b;}
12   bool operator<(const Point &a)const {return x*a.y-y*a.x>0;}
13 }p[6010],l[6010];
14 lol sumx[6010],sumy[6010],ans;
15 lol n,num;
16 Point operator -(Point a,Point b)
17 {
18   return Point(a.x-b.x,a.y-b.y);
19 }
20 bool cmp2(Point a,Point b)
21 {
22   return a.x==b.x?a.y<b.y:a.x<b.x;
23 }
24 int main()
25 {lol i,j;
26   cin>>n;
27   for (i=1;i<=n;i++)
28     {
29       scanf("%lld%lld",&p[i].x,&p[i].y);
30     }
31   sort(p+1,p+n+1,cmp2);
32   for (i=1;i<=n;i++)
33     {
34       for (j=i+1;j<=n;j++)
35       l[j]=p[j]-p[i];
36       sort(l+i+1,l+n+1);
37       sumx[n+1]=0;sumy[n+1]=0;
38       for (j=n;j>i;j--)
39       {
40         sumx[j]=sumx[j+1]+l[j].x;
41         sumy[j]=sumy[j+1]+l[j].y;
42         ans+=l[j].x*sumy[j+1]-l[j].y*sumx[j+1];
43       }
44     }
45   if (ans&1)
46     printf("%lld.5\n",ans/2);
47   else printf("%lld.0\n",ans/2);
48 }

 

posted @ 2018-04-03 08:06  Z-Y-Y-S  阅读(190)  评论(0编辑  收藏  举报