题目大意:给定平面上的一些点,求这些点能组成的所有三角形的面积之和
首先我们枚举每一个点 以这个点为原点建立平面直角坐标系 然后将第一、四象限和x、y轴正半轴上的点按照斜率排序
枚举第二个和第三个点 这样做是O(n^3)的 肯定超时 但是我们发现了什么?
对于每个点k 它对答案的贡献为:
(x1*yk-y1*xk)+(x2*yk-y2*xk)+...+(x_(k-1)*yk-y_(k-1)*xk)
=(x1+x2+...+x_(k-1))*yk-(y1+y2+...+y_(k-1))*xk
于是只要维护一个前缀和即可
时间复杂度O(n^2logn)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 3030 using namespace std; struct point{ int x,y; double slope; point(){} point(int _,int __):x(_),y(__) { slope=x?(double)y/x:1e10; } bool operator < (const point &Y) const { if(x!=Y.x) return x < Y.x; return y < Y.y; } }a[M],points[M]; int n,tot; long long ans; bool Compare(const point &p1,const point &p2) { return p1.slope < p2.slope; } int main() { int i,j; cin>>n; for(i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y); sort(a+1,a+n+1); for(i=1;i<=n;i++) { tot=0; long long sum_x=0,sum_y=0; for(j=i+1;j<=n;j++) points[++tot]=point(a[j].x-a[i].x,a[j].y-a[i].y); sort(points+1,points+tot+1,Compare); for(j=1;j<=tot;j++) { ans+=sum_x*points[j].y-sum_y*points[j].x; sum_x+=points[j].x; sum_y+=points[j].y; } } printf("%lld.%d\n",ans>>1,ans&1?5:0); }
原文地址:http://blog.csdn.net/popoqqq/article/details/41595241