题目链接

题意

给你一个凸多边形,求出在其内部选择一个点,这个点与最开始输入的两个点形成的三角形是以该点对凸多边形三角剖分的三角形中面积最小的一个三角形的概率。

Sol

答案就是 可行域面积与该凸多边形面积之比。

通过数学方法列出第一个三角形和其他三角形面积关系的式子,解出来发现都是一个半平面,所以我们要做的就是快速求解半平面交。

把所有要加入的直线用向量表示 , 按照极角排序 ( 用 atan2() ) , 然后依次加入直线。

维护一个双端队列 , 每次加入一条直线时判断最左最右的交点和当前直线的位置关系,如果点在不在加入向量的左侧那么要把最左或最右的直线弹掉。

加入完后还要判一下最右边交点和最左边的向量是否满足左右关系。

求完半平面交之后算个面积除一下就行了。

#include<bits/stdc++.h>
using namespace std;
#define Set(a,b) memset(a,b,sizeof(a))
template<class T>inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}typedef long long ll;
typedef double R;
#define Sqr(a) ((a)*(a))
const R PI=acos(-1),eps=1e-9,INF=1e9;
const int N=2e5+10;
struct point{
R x,y;
point(R _x=0.0,R _y=0.0) {x=_x,y=_y;}
inline R operator *(const point b){return x*b.y-y*b.x;}
inline point operator *(const R d){return point(x*d,y*d);}
inline point operator /(const R d){return point(x/d,y/d);}
inline point operator +(const point b){return point(x+b.x,y+b.y);}
inline point operator -(const point b){return point(x-b.x,y-b.y);}
inline void output(){printf("( %lf , %lf )",x,y);return;}
inline R len(){return sqrt(Sqr(x)+Sqr(y));}
}P[N];
struct line{
point A,B;R ang;
line(point _A=point(),point _B=point()){A=_A,B=_B;ang=atan2(B.y,B.x);}
inline bool operator <(const line b)const{return ang<b.ang;}
}L[N];int cnt=0;
int n;
inline int fcmp(R r){if(r>eps) return 1;else if(r<-eps) return -1;return 0;}
inline bool Left(point A,point B){return fcmp(A*B)>0;}
inline bool isleft(point A,line B){return fcmp(B.B*(A-B.A))>0;}
point Cr[N];R S=0;
inline point Inter(line L1,line L2){return L1.A+L1.B*((L2.B*(L2.A-L1.A))/(L2.B*L1.B));}
inline void HalfPlane(){
int l,r=1;sort(L+1,L+1+cnt);// 按照斜率(极角)排序
for(int i=2;i<=cnt;++i) {
if(fcmp(L[i].ang-L[r].ang)) L[++r]=L[i];
else if(isleft(L[i].A,L[r])) L[r]=L[i];
}
cnt=r,l=r=1;
for(int i=2;i<=cnt;++i) {// 类似维护凸包
while(l<r&&!isleft(Cr[r],L[i])) --r;
while(l<r&&!isleft(Cr[l+1],L[i])) ++l;// 交点必须在内部, 否则上一个向量没有用
L[++r]=L[i];
if(l<r) Cr[r]=Inter(L[r],L[r-1]);
}
while(l<r&&!isleft(Cr[r],L[l])) --r;
Cr[l]=Cr[r+1]=Inter(L[l],L[r]);
R area=0;
for(int i=l+2;i<=r;++i) area+=(Cr[i-1]-Cr[l])*(Cr[i]-Cr[l]);
printf("%.4lf\n",area/S);
}
int main()
{
init(n);S=0;
for(int i=1;i<=n;++i) {scanf("%lf %lf",&P[i].x,&P[i].y);}
for(int i=3;i<=n;++i) S+=(P[i-1]-P[1])*(P[i]-P[1]);
P[n+1]=P[1];
for(int i=1;i<=n;++i) {
point Q=P[i+1]-P[i];
L[++cnt]=line(P[i],Q);
}
R kx=P[1].y-P[2].y,ky=P[2].x-P[1].x,re=P[1].x*P[2].y-P[2].x*P[1].y;
for(int i=2;i<=n;++i){
R kxx=P[i].y-P[i+1].y,kyy=P[i+1].x-P[i].x,ree=P[i].x*P[i+1].y-P[i+1].x*P[i].y;
R kY=ky-kyy,kX=kxx-kx,Kre=ree-re;
if(kY) L[++cnt]=line(point(0,Kre/kY),point(-kY,-kX));
else if(kX) L[++cnt]=line(point(-Kre/kX,0),point(0,-kX));
}HalfPlane();
return 0;
}

【LuoguP4081】[SCOI2015]小凸想跑步的更多相关文章

  1. 【BZOJ4445】[Scoi2015]小凸想跑步 半平面交

    [BZOJ4445][Scoi2015]小凸想跑步 Description 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸n边形,N个顶点按照逆时针从0-n-l编号.现 ...

  2. 【BZOJ4445】[SCOI2015]小凸想跑步(半平面交)

    [BZOJ4445][SCOI2015]小凸想跑步(半平面交) 题面 BZOJ 洛谷 题解 首先把点给设出来,\(A(x_a,y_a),B(x_b,y_b),C(x_c,y_c),D(x_d,y_d) ...

  3. [SCOI2015]小凸想跑步

    题目描述 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 n 边形, nn 个顶点按照逆时针从 0 ∼n−1 编号.现在小凸随机站在操场中的某个位置,标记为p点.将 p ...

  4. BZOJ 4445 [Scoi2015]小凸想跑步:半平面交

    传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...

  5. bzoj 4445 [SCOI2015] 小凸想跑步

    题目大意:一个凸包,随机一个点使得其与前两个点组成的面积比与其他相邻两个点组成的面积小的概率 根据题意列方程,最后求n条直线的交的面积与原凸包面积的比值 #include<bits/stdc++ ...

  6. 洛谷P4250 [SCOI2015]小凸想跑步(半平面交)

    题面 传送门 题解 设\(p\)点坐标为\(x_p,y_p\),那么根据叉积可以算出它与\((i,i+1)\)构成的三角形的面积 为了保证\(p\)与\((0,1)\)构成的面积最小,就相当于它比其它 ...

  7. BZOJ4445: [Scoi2015]小凸想跑步

    裸半平面交. 记得把P0P1表示的半平面加进去,否则点可能在多边形外. #include<bits/stdc++.h> #define N 100009 using namespace s ...

  8. BZOJ4445 SCOI2015小凸想跑步(半平面交)

    考虑怎样的点满足条件.设其为(xp,yp),则要满足(x0-xp,y0-yp)×(x1-xp,y1-yp)<=(xi-xp,yi-yp)×(xi+1-xp,yi+1-yp)对任意i成立.拆开式子 ...

  9. 2018.10.15 bzoj4445: [Scoi2015]小凸想跑步(半平面交)

    传送门 话说去年的省选计算几何难度跟前几年比起来根本不能做啊(虽然去年考的时候并没有学过计算几何) 这题就是推个式子然后上半平面交就做完了. 什么? 怎么推式子? 先把题目的概率转换成求出可行区域. ...

随机推荐

  1. 人工智能06 能计划的agent

    能计划的agent 存储与计算 响应agent的动作功能几乎没有做任何计算.从本质上讲,这些agent执行的动作或者由他们的设计者.或者通过学习.或者通过演化过程.或者由以上几方面的组合来选择给他们的 ...

  2. windows 环境安装K8s

    文档地址: https://yq.aliyun.com/articles/508460?spm=a2c4e.11153940.blogcont221687.18.7dd57733hFolMo Dock ...

  3. 【GO】一个容易踩坑的内外变量屏蔽问题

    package main import ( "errors" "fmt" ) func et()(string,error){ return "&qu ...

  4. selenium—alert用法

    切换到弹框: switch_to_alert() ① alert.accept()  确认弹框 driver.switch_to_alert().accept() ② alert.dismiss() ...

  5. 搭建本地parcel仓库

    参考:https://www.cloudera.com/documentation/enterprise/6/6.2/topics/cm_ig_create_local_parcel_repo.htm ...

  6. 多标签分类(multi-label classification)综述

    意义 网络新闻往往含有丰富的语义,一篇文章既可以属于“经济”也可以属于“文化”.给网络新闻打多标签可以更好地反应文章的真实意义,方便日后的分类和使用. 难点 (1)类标数量不确定,有些样本可能只有一个 ...

  7. Configure脚本支持说明

    在Linux上安装Nginx需要执行Configure脚本,该脚本需要做一些参数说明: 选项 说明 --prefix=<path> 指定Nginx软件的安装路径,若不指定默认安装在/usr ...

  8. Intellij IDEA中使用Debug调试

    转自:https://blog.csdn.net/zj420964597/article/details/78662299只是为了方便学习技术,少走弯路,如果有异议,请留言,及时处理!!!

  9. Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态)

    Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态) 1.面向对象的三大特性: (1)继承 ​ 继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可以 ...

  10. spark教程(14)-共享变量

    spark 使用的架构是无共享的,数据分布在不同节点,每个节点有独立的 CPU.内存,不存在全局的内存使得变量能够共享,驱动程序和任务之间通过消息共享数据 举例来说,如果一个 RDD 操作使用了驱动程 ...