题目描述

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

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

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

题解

我们其实是要找到一个p点,使得pp0*pp1<=ppi*ppi+1.

然后我们把上面的式子展开,然后化简,这个不难就是挺麻烦的。

最后得到了Ax+By+C<=0的形式,然后可以用(-1e9,y1)(1e9,y2)这条直线来描述这个限制,再加上凸多边形的限制,跑个半平面交就好了。

注意:要特判A或B=0的情况。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#define N 200009
#define double long double
#define eq(x,y) (fabs((x)-(y))<eps)
using namespace std;
const double eps=1e-;
int n,top,tot;
double x[N],y[N],s,S;
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
struct point{
double x,y;
point(double xx=,double yy=){x=xx;y=yy;}
inline point operator +(const point &b)const{return point{x+b.x,y+b.y};}
inline point operator -(const point &b)const{return point{x-b.x,y-b.y};}
inline double operator *(const point &b)const{return x*b.y-y*b.x;}
inline point operator *(const double &b)const{return point{x*b,y*b};}
}p[N];
struct line{
point x,y;double ang;
line(double x1=,double x2=,double x3=,double x4=){x.x=x1;x.y=x2;y.x=x3;y.y=x4;}
bool operator <(const line &b)const{
if(fabs(ang-b.ang)<eps)return (y-x)*(b.x-x)<eps;
else return ang<b.ang;
}
}a[N],l[N],q[N];
inline bool left(point a,line b){return (a-b.x)*(b.y-b.x)>-eps;}
inline point jiao(line a,line b){return b.x+(b.y-b.x)*(((b.x-a.x)*(a.y-a.x))/((a.y-a.x)*(b.y-b.x)));}
int main(){
n=rd();
for(int i=;i<n;++i){
x[i]=rd(),y[i]=rd();
if(i)l[++top]=line(x[i-],y[i-],x[i],y[i]);
}
l[++top]=line(x[n-],y[n-],x[],y[]);
for(int i=;i<n;++i)S+=(point(x[i],y[i])-point(x[],y[]))*(point{x[i-],y[i-]}-point{x[],y[]})/;S=fabs(S);
x[n]=x[];y[n]=y[];
for(int i=;i<n;++i){
double a=-y[]+y[]+y[i+]-y[i],b=-x[]+x[]+x[i]-x[i+],c=x[]*y[]-x[]*y[]-x[i]*y[i+]+x[i+]*y[i];
if(fabs(b)<eps){
if(fabs(a)<eps){puts("0.0000");return ;}
double xf=-c/a,xs=xf,yf=,ys=1e15;
if(a<)l[++top]=line(xs,ys,xf,yf);
else l[++top]=line(xf,yf,xs,ys);
}
else{
double xf=-1e11,xs=1e11,yf=(-c-a*xf)/b,ys=(-c-a*xs)/b;
if(b>=){l[++top]=line(xs,ys,xf,yf);
}else l[++top]=line(xf,yf,xs,ys);
}
}
for(int i=;i<=top;++i)l[i].ang=atan2(l[i].y.y-l[i].x.y,l[i].y.x-l[i].x.x);
sort(l+,l+top+);
for(int i=;i<=top;++i)if(i==||fabs(l[i].ang-l[i-].ang)>eps)a[++tot]=l[i];
int h=,t=;q[]=a[];q[]=a[];p[]=jiao(a[],a[]);
for(int i=;i<=tot;++i){
while(h<t&&left(p[t-],a[i]))t--;
while(h<t&&left(p[h],a[i]))h++;
q[++t]=a[i];p[t-]=jiao(q[t-],q[t]);
}
while(h<t&&left(p[h],q[t]))h++;
while(h<t&&left(p[t-],q[h]))t--;
p[t]=jiao(q[t],q[h]);
for(int i=h+;i<=t;++i)s+=(p[i]-p[h])*(p[i-]-p[h])/;s=fabs(s);
printf("%.4LF",s/S);
return ;
}

[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. BZOJ 4445 [Scoi2015]小凸想跑步:半平面交

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

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

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

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

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

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

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

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

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

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

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

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

    题意:凸包上一个点\(p\),使得\(p\)和点\(0,1\)组成的三角形面积最小 用叉积来求: \(p,i,i+1\)组成的三角形面积为: (\(\times\)为叉积) \((p_p-i)\tim ...

随机推荐

  1. Android细笔记--DataStorage

    Shared Preferences 即使应用被杀了,shared preference也还是存在的 Internal Storage 创建于internal的文件只对本应用开放权限,即使手机用户本身 ...

  2. Thinkphp5整合微信扫码支付开发实例

    ThinkPHP框架是比较多人用的,曾经做过的一个Thinkphp5整合微信扫码支付开发实例,分享出来大家一起学习 打开首页生成订单,并显示支付二维码 public function index() ...

  3. Java新知识系列 七

    抽象类和接口的区别和特点 java的JDK中包含的五个工具 编译型语言和解释型语言 Java和C++的区别` 常见的ASCII的值 Forward和Redirect之间的对比 Web Service ...

  4. redis 五大数据结构__常用命令

    linux 下下载redis数据库 apt install redis 如果提示权限不够的话, 直接提权: sudo apt install redis-server linux启用.停止服务 ser ...

  5. 解决TOC与目录导航冲突问题

    TOC是指markdown的TOC; 目录导航是指博客园中各个博主提供的各种目录导航. 现在改换markdown写博文了,我喜欢使用TOC作为目录,让大家了解博文的内容,也喜欢用"目录导航& ...

  6. Vue一个案例引发「内容分发slot」的最全总结

    今天我们继续来说说 Vue,目前一直在自学 Vue 然后也开始做一个项目实战,我一直认为在实战中去发现问题然后解决问题的学习方式是最好的,所以我在学习一些 Vue 的理论之后,就开始自己利用业余时间做 ...

  7. 注册Github过程

    第一步当然是建立自己的账号密码了: 一: github官网地址:https://github.com/ (1)第一步:首先起一个属于自己用户的名字(username),用户名字只能包含字母数字的字符或 ...

  8. FIDDLER的使用方法及技巧总结

    转自: https://www.cnblogs.com/ink-marks/p/6363275.html 一.FIDDLER快速入门及使用场景 Fiddler的官方网站:http://www.fidd ...

  9. centosFTP服务搭建及权限配置

    引用一个其他大佬对vsftpd的描述: vsftpd 是“very secure FTP daemon”的缩写,安全性是它的一个最大的特点. vsftpd 是一个 UNIX 类操作系统上运行的服务器的 ...

  10. 使用Java反射优化多个方法调用

    有段时间没来写博客了,心里一直念叨空了来,今天有时间来记录一篇.前段时间领导提出优化部分系统模块,根据业务要求系统中有很多产品,产品下面有N个指标,一个指标就对应一个方法,所以系统代码中就是这样一个情 ...