题目链接

题意

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

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. MyBatis 简单入门

    添加maven 依赖 <dependencies> <dependency> <groupId>org.mybatis</groupId> <ar ...

  2. redhat 5 中文乱码

    安装 1.fonts-chinese-3.02-9.6.el5.noarch.rpm. 如果无法安装,则加个--force 2.fonts-ISO8859-2-75dpi-1.0-17.1.noarc ...

  3. pypy3.6的下载地址和安装第三方依赖

    1.不同版本的下载链接 建议使用此链接:https://bitbucket.org/pypy/pypy/downloads/ 官网的:http://doc.pypy.org/en/latest/rel ...

  4. C++学习笔记-多态

    多态作为面向对象的重要概念,在如何一门面向对象编程语言中都有着举足轻重的作用,学习多态,有助于更好地理多态的行为 多态性(Polymorphism)是指一个名字,多种语义:或界面相同,多种实现. 重载 ...

  5. 【linux杂谈】遇到REMOTE HOST IDENTIFICATION HAS CHANGED怎么办?

    今日遇到如下问题: 警告的大概意思就是,主机密钥发生变更,并提示安全风险(可能存在中间人攻击) 但是事实是,这是因为我重装系统之后遇到的问题.重装系统后,指纹当然会发生变化了...在Xshell实验中 ...

  6. hbase的hue部署和使用

    1.组件版本信息 zookeeper hadoop hbase     hue           zookeeper-3.4.12 hadoop-3.0.3 hbase-2.1.5 4.4.0 2. ...

  7. AS将一个项目导入到另一个项目中

    需求:有项目A,B.需要将B集成到A中,作为A的一个模块. 方法: 1.将B工程的app下面的build.gradle文字中  apply plugin: 'com.android.applicati ...

  8. PTA(Advanced Level)1031.Hello World for U

    Given any string of N (≥5) characters, you are asked to form the characters into the shape of U. For ...

  9. hello2源代码分析

    String username = request.getParameter("username");/* *以 String 形式返回请求参数"username&quo ...

  10. Java回调实现异步

    在正常的业务中使用同步线程,如果服务器每处理一个请求,就创建一个线程的话,会对服务器的资源造成浪费.因为这些线程可能会浪费时间在等待网络传输,等待数据库连接等其他事情上,真正处理业务逻辑的时间很短很短 ...