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 }