【BZOJ1132】[POI2008] Tro(计算几何水题)

点此看题面

大致题意: 给定$n$个点,求所有以这些点为顶点的三角形面积之和。

排序

考虑三角形面积计算公式:

\(\frac{|\vec{AB}\times \vec{AC}|}2\)

显然,绝对值是一个麻烦的东西,因此我们要想办法让$\vec\times\vec$必然是个正值。

怎么办呢?

排序一下就好了呀!

于是我们枚举顶点$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
}
posted @ 2020-06-08 14:39  TheLostWeak  阅读(19)  评论(0编辑  收藏