zoukankan      html  css  js  c++  java
  • P4250 [SCOI2015]小凸想跑步

    题意描述:

    Link

    给你一个凸多边形,其顶点为 (A_i), 你从多边形内部任选一个点 (p), 求 满足 (S_{Delta PA_0A_1} leq S_{Delta PA_iA_{i+1}}) 的概率。

    题解:

    由题意可得: (S_{Delta PA_0A_1} < S_{Delta PA_iA_{i+1}})

    然后就开始暴力展开,推柿子。

    (vec {A_0A_1} imes vec{A_0P} <vec{A_iA_{i+1}} imes vec {A_iP})(满足叉积都是正的)

    设 $P = (x,y) $ , (A_i = (x_i,y_i)) ,则有:

    ((x_1-x_0,y_1-y_0) imes (x-x_0,y-y_0) < (x_{i+1}-x_i,y_{i+1}-y_i) imes (x-x_i,y-y_i))

    ((x_1-x_0)(y-y_0) - (x-x_0)(y_1-y_0) < (x_{i+1}-x_i)(y-y_i) - (x-x_i) (y_{i+1}-y_i))

    (x_1y-x_1y_0-x_0y+x_0y_0 - (xy_1-xy_0-x_0y_1+x_0y_0) < x_{i+1}y - x_{i+1}y_i- x_iy + x_iy_i - (xy_{i+1} - xy_i - x_{i}y_{i+1} + x_iy_i))

    $x_1y-x_1y_0-x_0y-xy_1+xy_0+x_0y_1 < x_{i+1}y-x_{i+1}y_i - x_iy - xy_{i+1} + xy_i + x_iy_{i+1} $

    $(y_0-y_1) x + (x_1-x_0)y + x_0y_1 - x_1y_0 < (y_i-y_{i+1})x + (x_{i+1}-x_i)y + x_iy_{i+1} -x_{i+1}y_i $

    ((y_0-y_1-y_i+y_{i+1})x + (x_1-x_0-x_{i+1}+x_i)y + x_0y_1-x_1y_0 + x_{i+1}y_{i} - x_iy_{i+1} < 0)

    ((y_1-y_0-y_{i+1}+y_i) x + (x_0-x_1 - x_i+x_{i+1})y + x_1 y_0-x_0y_1 + x_{i}y_{i+1} - x_{i+1}y_{i} > 0)

    很显然这是个半平面交的形式。

    那么合法的 (p) 的区域就是半平面的交。

    最后的答案就是多边形面积除以半平面交区域的面积。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N = 2e5+10;
    const double eps = 1e-8;
    int n,l,r,cnt,top;
    double ans1,ans2;
    struct point
    {
        double x,y;
        point(){}
        point(double a,double b){x = a, y = b;}
    }p[N],sta[N],Ans[N];
    typedef point Vector;
    struct line
    {
        point x,v;
        double ang;
        line(){}
        line(point a,point b)
        {
            x = a; v = b;
            ang = atan2(b.y,b.x);
        }
    }L[N],q[N];
    int dcmp(double x)
    {
        if(fabs(x) < eps) return 0;
        return x > 0 ? 1 : -1;
    }
    point operator + (point a,point b){return point(a.x+b.x,a.y+b.y);}
    point operator - (point a,point b){return point(a.x-b.x,a.y-b.y);}
    point operator * (point a,double k){return point(a.x*k,a.y*k);}
    double Dot(point a,point b){return a.x*b.x+a.y*b.y;}
    double Cro(point a,point b){return a.x*b.y-a.y*b.x;}
    double dis(point a,point b){return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}
    bool OnRight(point p,line s){return dcmp(Cro(p-s.x,s.v)) >= 0;}
    point Root_LL(line a,line b)
    {
        Vector v = a.v, u = b.v, w = a.x-b.x;
        double t = Cro(w,u) / Cro(u,v);
        return a.x + v * t;
    }
    bool comp(line a,line b)
    {
        if(dcmp(a.ang-b.ang) == 0) return OnRight(b.x,a);
        return a.ang < b.ang;
    }
    void HPI()
    {
        sort(L+1,L+cnt+1,comp);
        l = 1, r = 1, q[1] = L[1];
        for(int i = 2; i <= cnt; i++)
        {
            if(dcmp(L[i].ang-L[i-1].ang) == 0) continue;
            while(l < r && OnRight(sta[r-1],L[i])) r--;
            while(l < r && OnRight(sta[l],L[i])) l++;
            q[++r] = L[i];
            if(l < r) sta[r-1] = Root_LL(q[r],q[r-1]);
        }
        while(l < r && OnRight(sta[r-1],q[l])) r--;
        while(l < r && OnRight(sta[l],q[r])) l++;
        sta[r] = Root_LL(q[l],q[r]);
        for(int i = l; i <= r; i++) Ans[++top] = sta[i];
    }
    int main()
    {
        scanf("%d",&n);
        for(int i = 0; i < n; i++) scanf("%lf%lf",&p[i].x,&p[i].y);
        for(int i = 1; i < n; i++) ans1 += Cro(p[i]-p[0],p[(i+1)%n]-p[0]);
        for(int i = 0; i < n; i++) L[++cnt] = line(p[i],p[(i+1)%n]-p[i]);
        for(int i = 1; i < n; i++)
        {
            int t = (i+1) % n;
            double A = p[0].y - p[1].y - p[i].y + p[t].y;
            double B = p[1].x - p[0].x - p[t].x + p[i].x;
            double C = p[0].x * p[1].y - p[1].x * p[0].y + p[t].x * p[i].y - p[i].x * p[t].y;
            if(dcmp(B) == 0) L[++cnt] = line(point(-C/A,0),point(-B,A));
            else L[++cnt] = line(point(0,-C/B),point(-B,A));
        }
        HPI();
        for(int i = 2; i < top; i++) ans2 += Cro(Ans[i]-Ans[1],Ans[i+1]-Ans[1]);
        printf("%.4lf
    ",ans2/ans1);
        return 0;
    }
    
  • 相关阅读:
    Cocos2dx开发(3)——Cocos2dx打包成APK,ANT环境搭建
    Cocos2dx开发(2)——Win8.1下Cocod2dx 3.2环境搭建
    Cocos2dx开发(1)——Win8.1下 NDK r10 环境搭建
    设计模式备忘录(1):适配器模式、依赖注入依赖倒置、空对象模式
    使用latencytop深度了解你的系统的延迟(转)
    操作系统基础
    计算机基础
    说明exit()函数作用的程序
    变量的引用类型和非引用类型的区别
    二进制转16进制JAVA代码
  • 原文地址:https://www.cnblogs.com/genshy/p/14350705.html
Copyright © 2011-2022 走看看