ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

bzoj4445&&dtoj#2348. 小凸想跑步(convex)

2019-03-07 10:41:50  阅读:239  来源: 互联网

标签:node const db 2348 t1 bzoj4445 convex return line


题目描述:

小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏。

操场是个凸 $n$ 边形,n个顶点按照逆时针从 $0$ ~ $n-1$ 编号。现在小凸随机站在操场的某个位置,标记为 $p$ 点。将 $p$ 点与 $n$ 个顶点各连一条边,形成n个三角形。如果这时 $p$ 点, $0$ 号点, $1$ 号点形成的三角形的面积是 $n$ 个三角形中最小的一个,小凸则认为这是一次正确站位。

现在小凸想知道他一次站位正确的概率是多少。

输入:

第 $1$ 行包含 $1$ 个整数 $n$ ,表示操场的顶点数和游戏的次数。

接下来有 $n$ 行,每行包含 $2$ 个整数 $x_{i},y_{i}$ ,表示顶点的坐标。

输入保证按逆时针顺序输入点,所有点保证构成一个凸多边形。所有点保证不存在三点共线。

算法标签:半平面交

jzy的半平面交初体验=抄代码

思路:

对于站位有两种限制条件,第一种是要在凸多边形内部,第二种对于每一条边建立使得这个点与这条边的构成三角形的面积小于等于这个点与 $0,1$ 号边构成三角形的面积。

用叉积求面积的方法列出三角形面积的式子,可以求得一个不等式。

对于所有的不等式求半平面交,最后在求半平面交围成的面积。

以下代码:

#include<bits/stdc++.h>
#define il inline
#define db double
#define _(d) while(d(isdigit(ch=getchar())))
using namespace std;
const int N=2e5+5;
db sum,ans;
int n,tot,q[N],cnt;
struct node{
    db x,y;
    node(){}
    node(db a,db b){x=a;y=b;}
    node operator + (const node &t1) const {return node(x+t1.x,y+t1.y);}
    node operator - (const node &t1) const {return node(x-t1.x,y-t1.y);}
    node operator * (const db &t1) const {return node(x*t1,y*t1);}
}t[N],p[N];
struct line{
    node a,b;
    db k;
    line(){};
    line(node t1,node t2){
        a=t1;b=t2;k=atan2(b.y,b.x);
    }
}l[N];
il int read(){
    int x,f=1;char ch;
    _(!)ch=='-'?f=-1:f;x=ch^48;
    _()x=(x<<1)+(x<<3)+(ch^48);
    return f*x;
}
il db cross(node a,node b){
    return a.x*b.y-a.y*b.x;
}
il node P(line a,line b){
    node u=a.a-b.a;
    db tmp=cross(b.b,u)/cross(a.b,b.b);
    return a.a+a.b*tmp;
}
il bool ol(line t1,node t2){
    return cross(t1.b,t2-t1.a)>=0;
}
bool cmp(const line &t1,const line &t2){
    if(fabs(t1.k-t2.k)==0)return ol(t1,t2.a);
    return t1.k<t2.k;
}
il void HPI(){
    sort(l+1,l+1+tot,cmp);
    int j=1;
    for(int i=2;i<=tot;i++)
        if(fabs(l[i].k-l[j].k)>0)l[++j]=l[i];
    tot=j;int h=1,t=2;q[1]=1;q[2]=2;
    for(int i=3;i<=tot;i++){
        while(h<t&&ol(l[i],P(l[q[t-1]],l[q[t]])))t--;
        while(h<t&&ol(l[i],P(l[q[h+1]],l[q[h]])))h++;
        q[++t]=i;
    }
    while(h<t&&ol(l[q[h]],P(l[q[t-1]],l[q[t]])))t--;
    for(int i=h;i<t;i++)p[i]=P(l[q[i]],l[q[i+1]]);
    p[t]=P(l[q[t]],l[q[h]]);
    for(int i=h+1;i<t;i++){
        ans+=cross(p[i]-p[h],p[i+1]-p[h]);
    }
}
int main()
{
    n=read();
    for(int i=0;i<n;i++)t[i].x=read(),t[i].y=read();
    t[n]=t[0];
    for(int i=1;i<n-1;i++)
        sum+=cross(t[i]-t[0],t[i+1]-t[0]);
    for(int i=0;i<n;i++)l[++tot]=line(t[i+1],t[i]-t[i+1]);
    for(int i=1;i<n;i++){
        db a=t[i+1].y-t[i].y-t[1].y+t[0].y;
        db b=t[i+1].x-t[i].x-t[1].x+t[0].x;
        db c=cross(t[i+1],t[i])-cross(t[1],t[0]);
        if(fabs(b)>0)l[++tot]=line(node(0,c/b),node(-b,-a));
        else if(fabs(a)>0)l[++tot]=line(node(-c/a,0),node(0,-a));
    }
    HPI();
    printf("%.4lf\n",ans/sum);
    return 0;
}
View Code

 

标签:node,const,db,2348,t1,bzoj4445,convex,return,line
来源: https://www.cnblogs.com/Jessie-/p/10487931.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有