题解
叉积求三角形面积都会,这题最难解决的就是abs的问题。需要确定一个顺序,让我们确切的知道哪些需要取负号,哪些不用。
在学习graham scan的时候,有一个操作就是找到最左下角的点,所有的点减去这个点然后按照叉积排序。
这个题同样,按照横坐标排序,以每个点为坐标原点重新建系(次序在前面的点就不考虑了),显然这个时候任意两个向量的叉积都为正。
代码
//计算几何
#include <cstdio>
#include <algorithm>
#define maxn 3050
#define ll long long
using namespace std;
int N, tot;
ll ans, sx, sy;
struct point{int x, y;}pt[maxn], list[maxn];
bool operator<(const point &p1, const point &p2){return p1.x<p2.x;}
ll operator*(const point &p1, const point &p2){return p1.x*p2.y-p2.x*p1.y;}
bool cmp(point p1, point p2){return p1*p2<0;}
void solve()
{
int i, j;
sort(pt+1,pt+N+1);
for(i=1;i<=N;i++)
{
tot=0;
sx=sy=0;
for(j=i+1;j<=N;j++)
sx+=pt[j].x-pt[i].x, sy+=pt[j].y-pt[i].y,
list[++tot]=(point){pt[j].x-pt[i].x,pt[j].y-pt[i].y};
sort(list+1,list+tot+1,cmp);
for(j=1;j<=tot;j++)
{
sx-=list[j].x, sy-=list[j].y;
ans+=sx*list[j].y-list[j].x*sy;
}
}
}
int main()
{
int i;
scanf("%d",&N);
for(i=1;i<=N;i++)scanf("%d%d",&pt[i].x,&pt[i].y);
solve();
printf("%lld.%lld",ans>>1,(ans&1)*5);
return 0;
}