您的位置:首页 > 其它

BZOJ_1132_[POI2008]Tro_计算几何

2018-05-20 12:13 393 查看

BZOJ_1132_[POI2008]Tro_计算几何

Description

平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和 N<=3000

Input

第一行给出数字N,N在[3,3000] 下面N行给出N个点的坐标,其值在[0,10000]

Output

保留一位小数,误差不超过0.1

Sample Input

5
0 0
1 2
0 2
1 0
1 1

Sample Output

7.0 把面积转换成叉积的形式,也就是说我们要求$\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=j+1}^{n}|(y_i-y_j)*(x_k-x_i)-(y_k-y_i)*(x_j-x_i)|$ 然后枚举i,以第i个点为原点对其他那些点进行极角排序,维护一个前缀和把绝对值化掉,统计那些是加哪些是减即可。   代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long f2;
#define eps 1e-7
#define N 3050
struct Point {
f2 x,y;
Point() {}
Point(f2 x_,f2 y_) :
x(x_),y(y_) {}
Point operator + (const Point &p) const {return Point(x+p.x,y+p.y);}
Point operator - (const Point &p) const {return Point(x-p.x,y-p.y);}
bool operator < (const Point &p) const {
if(y==p.y) return x<p.x; return y<p.y;
}
}a
,t
;
typedef Point Vector;
int n;
f2 sx
,sy
;
f2 cross(const Point &p1,const Point &p2) {return p1.x*p2.y-p1.y*p2.x;}
bool cmp(const Vector &x,const Vector &y) {
return cross(x,y)>eps;
}
int main() {
scanf("%d",&n);
int i,j;
for(i=1;i<=n;i++) {
scanf("%lld%lld",&a[i].x,&a[i].y);
}
sort(a+1,a+n+1);
f2 ans=0;
for(i=1;i<=n-2;i++) {
for(j=i+1;j<=n;j++) t[j]=a[j]-a[i];
sort(t+i+1,t+n+1,cmp);
sx[i]=sy[i]=0;
for(j=i+1;j<=n;j++) {
sx[j]=sx[j-1]+t[j].x;
sy[j]=sy[j-1]+t[j].y;
}
for(j=i+1;j<=n;j++) {
ans+=(t[j].x*(sy
-sy[j])-t[j].y*(sx
-sx[j]));
}
}
printf("%lld.%lld\n",ans/2,ans%2*5);
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: