题目大意:给定平面上的一些点,求这些点能组成的所有三角形的面积之和
首先我们枚举每一个点 以这个点为原点建立平面直角坐标系 然后将第一、四象限和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);
}