【LuoguP4081】[SCOI2015]小凸想跑步
题意
给你一个凸多边形,求出在其内部选择一个点,这个点与最开始输入的两个点形成的三角形是以该点对凸多边形三角剖分的三角形中面积最小的一个三角形的概率。
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]小凸想跑步的更多相关文章
- 【BZOJ4445】[Scoi2015]小凸想跑步 半平面交
[BZOJ4445][Scoi2015]小凸想跑步 Description 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸n边形,N个顶点按照逆时针从0-n-l编号.现 ...
- 【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) ...
- [SCOI2015]小凸想跑步
题目描述 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 n 边形, nn 个顶点按照逆时针从 0 ∼n−1 编号.现在小凸随机站在操场中的某个位置,标记为p点.将 p ...
- BZOJ 4445 [Scoi2015]小凸想跑步:半平面交
传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...
- bzoj 4445 [SCOI2015] 小凸想跑步
题目大意:一个凸包,随机一个点使得其与前两个点组成的面积比与其他相邻两个点组成的面积小的概率 根据题意列方程,最后求n条直线的交的面积与原凸包面积的比值 #include<bits/stdc++ ...
- 洛谷P4250 [SCOI2015]小凸想跑步(半平面交)
题面 传送门 题解 设\(p\)点坐标为\(x_p,y_p\),那么根据叉积可以算出它与\((i,i+1)\)构成的三角形的面积 为了保证\(p\)与\((0,1)\)构成的面积最小,就相当于它比其它 ...
- BZOJ4445: [Scoi2015]小凸想跑步
裸半平面交. 记得把P0P1表示的半平面加进去,否则点可能在多边形外. #include<bits/stdc++.h> #define N 100009 using namespace s ...
- BZOJ4445 SCOI2015小凸想跑步(半平面交)
考虑怎样的点满足条件.设其为(xp,yp),则要满足(x0-xp,y0-yp)×(x1-xp,y1-yp)<=(xi-xp,yi-yp)×(xi+1-xp,yi+1-yp)对任意i成立.拆开式子 ...
- 2018.10.15 bzoj4445: [Scoi2015]小凸想跑步(半平面交)
传送门 话说去年的省选计算几何难度跟前几年比起来根本不能做啊(虽然去年考的时候并没有学过计算几何) 这题就是推个式子然后上半平面交就做完了. 什么? 怎么推式子? 先把题目的概率转换成求出可行区域. ...
随机推荐
- 对JavaScript事件处理程序/事件监听器的设定的简单介绍
下面是一些对事件处理进行设定的方式. 指定为HTML元素的属性(事件处理程序) 指定为DOM元素的属性(事件处理程序) 通过EventTarget.addEventListener()进行指定(事件监 ...
- cisco路由器配置(三) 最终网关
Gateway(config)#ip route 0.0.0.0 0.0.0.0 217.124.6.1 /*管理距离为1/orGateway(config)#ip route 0.0.0.0 0. ...
- 【VS开发】MFC运行时库与debug、release版本之间的配置关系
参考内容: 前段时间从网上下来一个有意思的代码,用VS2010打开时需要将工程转换为2010的工程,转化后却出现了编译不通过的问题,类似这样的错误:c:\program files\microsoft ...
- 非常好的一个JS代码(FixedMenu.htm)
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- SpringBoot配置文件值植入
<!‐‐导入配置文件处理器,配置文件进行绑定就会有提示‐‐> <dependency> <groupId>org.springframework.boot</ ...
- 系统的可用性用平均无故障时间( MTTF)
计算机系统的可用性用平均无故障时间( MTTF)来度量,即计算机系统平均能够正常运行多长时间,才发生一次故障.系统的可用性越高,平均无故障时间越长. 可维护性用平均维修时间(MTTR)来度量,即系统发 ...
- Docker部署前后端项目
本地(ubuntu19.04)安装docker: sudo apt install docker.io SSH连接服务器: 安装Docker: yum update yum -y install do ...
- Django2.1 authenticate 会关联数据库 is_active 的解决办法
# 会检测用户是否是活跃状态(is_active),不活跃则返回None(默认配置)AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.M ...
- 03:linux文件操作四剑客
1.1 find查找命令 1.find命令说明 1. Linux find命令用来在指定目录下查找文件. 2. 任何位于参数之前的字符串都将被视为欲查找的目录名. 3. 如果使用该命令时,不设置任何参 ...
- 从入门到自闭之Python时间模块
time模块:import time time.time():时间戳,是一个浮点数,按秒来计算 time.sleep():睡眠,程序暂停多少秒执行 python中时间日期格式化符号: 必背 %y 两位 ...