BZOJ 1132 POI2008 Tro 计算几何

来源:互联网 发布:单片机的发展趋势 编辑:程序博客网 时间:2024/04/30 13:42

题目大意:给定平面上的一些点,求这些点能组成的所有三角形的面积之和

首先我们枚举每一个点 以这个点为原点建立平面直角坐标系 然后将第一、四象限和x、y轴正半轴上的点按照斜率排序

枚举第二个和第三个点 这样做是O(n^3)的 肯定超时 但是我们发现了什么?

对于每个点k 它对答案的贡献为:

(x1*yk-y1*xk)+(x2*yk-y2*xk)+...+(x_(k-1)*yk-y_(k-1)*xk)

=(x1+x2+...+x_(k-1))*yk-(y1+y2+...+y_(k-1))*xk

于是只要维护一个前缀和即可

时间复杂度O(n^2logn)

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 3030using namespace std;struct point{    int x,y;    double slope;    point(){}    point(int _,int __):x(_),y(__)    {        slope=x?(double)y/x:1e10;    }    bool operator < (const point &Y) const    {        if(x!=Y.x)            return x < Y.x;        return y < Y.y;    }}a[M],points[M];int n,tot;long long ans;bool Compare(const point &p1,const point &p2){    return p1.slope < p2.slope;}int main(){    int i,j;    cin>>n;    for(i=1;i<=n;i++)        scanf("%d%d",&a[i].x,&a[i].y);    sort(a+1,a+n+1);    for(i=1;i<=n;i++)    {        tot=0;        long long sum_x=0,sum_y=0;        for(j=i+1;j<=n;j++)            points[++tot]=point(a[j].x-a[i].x,a[j].y-a[i].y);        sort(points+1,points+tot+1,Compare);        for(j=1;j<=tot;j++)        {            ans+=sum_x*points[j].y-sum_y*points[j].x;            sum_x+=points[j].x;            sum_y+=points[j].y;        }    }    printf("%lld.%d\n",ans>>1,ans&1?5:0);}


0 0
原创粉丝点击