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

点此看题面

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

排序

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

[frac{|vec{AB} imes vec{AC}|}2 ]

显然,绝对值是一个麻烦的东西,因此我们要想办法让(vec{AB} imesvec{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
}
原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ1132.html