【BZOJ1132】[POI2008] Tro(计算几何水题)
大致题意: 给定\(n\)个点,求所有以这些点为顶点的三角形面积之和。
排序
考虑三角形面积计算公式:
\[\frac{|\vec{AB}\times \vec{AC}|}2
\]
显然,绝对值是一个麻烦的东西,因此我们要想办法让\(\vec{AB}\times\vec{AC}\)必然是个正值。
怎么办呢?
排序一下就好了呀!
于是我们枚举顶点\(A\),求出所有向量之后累计顶点\(B\)的横纵坐标之和,然后枚举\(C\)叉积计算答案。
具体实现详见代码。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 3000
using namespace std;
int n;struct P
{
int x,y;I P(CI a=0,CI b=0):x(a),y(b){}
I P operator - (Con P& o) Con {return P(x-o.x,y-o.y);}
I bool operator < (Con P& o) Con {return x*o.y-y*o.x>0;}//保证叉积大于0
}s[N+5],p[N+5];
I bool cmp(Con P& x,Con P& y) {return x.y^y.y?x.y<y.y:x.x<y.x;}//初始化排序
int main()
{
RI i,j;for(scanf("%d",&n),i=1;i<=n;++i) scanf("%d%d",&s[i].x,&s[i].y);
long long t=0;RI x,y;for(sort(s+1,s+n+1,cmp),i=1;i<=n;++i)//枚举A
{
for(j=i+1;j<=n;++j) p[j-i]=s[j]-s[i];sort(p+1,p+n-i+1);//记下向量
for(x=y=0,j=1;j<=n-i;++j) t+=1LL*x*p[j].y-1LL*y*p[j].x,x+=p[j].x,y+=p[j].y;//t统计答案,x,y累计B的横纵坐标
}return printf("%lld.%c",t>>1,t&1?'5':'0'),0;//注意除以2
}
待到再迷茫时回头望,所有脚印会发出光芒