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

题面

BZOJ

洛谷

题解

首先把点给设出来,\(A(x_a,y_a),B(x_b,y_b),C(x_c,y_c),D(x_d,y_d),P(x,y)\)

然后我们考虑\(S_\Delta ABP<S_\Delta CDP\)什么情况下满足。

根据点积来求面积,得到:

\[(x_a-x,y_a-y)\times(x_b-x,y_b-y)<(x_c-x,y_c-y)\times(x_d-x,y_d-y)
\]

这个东西左边拆开之后得到:

\[\begin{aligned}
&\ \ \ \ (x_a-x)(y_b-y)-(x_b-x)(y_a-y)\\
&=x(y_a-y_b)-y(x_a-x_b)+x_ay_b-x_by_a
\end{aligned}\]

右侧类似。然后就可以移项,得到:

\[x(y_a-y_b-y_c+y_d)-y(x_a-x_b-x_c+x_d)+x_ay_b-x_by_a-x_cy_d+x_dy_c<0
\]

那么对于相邻的两个点和\(0,1\)两个点进行一次比较,每次都可以得到一个半平面,最后求解这个半平面交就是结果了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAX 100100
const double eps=1e-7;
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Node{double x,y;}p[MAX],Qp[MAX<<1];
Node operator+(Node a,Node b){return (Node){a.x+b.x,a.y+b.y};}
Node operator-(Node a,Node b){return (Node){a.x-b.x,a.y-b.y};}
Node operator*(Node a,double b){return (Node){a.x*b,a.y*b};}
double operator*(Node a,Node b){return a.x*b.x+a.y*b.y;}
double cross(Node a,Node b){return a.x*b.y-a.y*b.x;}
struct Line{Node p,v;double alpha;}S[MAX<<1],Q[MAX<<1];int tot;
bool cmp(Line a,Line b){return a.alpha<b.alpha;}
Node Intersection(Line a,Line b)
{
Node c=b.p-a.p;
double t=cross(b.v,c)/cross(b.v,a.v);
return a.p+a.v*t;
}
int zero(double x)
{
if(fabs(x)<eps)return 0;
return x>0?1:-1;
}
bool Left(Node a,Line b){return zero(cross(b.v,a-b.p))>0;}
int n;double area;
int l,r;
bool HalfPlaneIntersection()
{
for(int i=1;i<=tot;++i)S[i].alpha=atan2(S[i].v.y,S[i].v.x);
sort(&S[1],&S[tot+1],cmp);
Q[l=r=1]=S[1];
for(int i=2;i<=tot;++i)
{
while(l<r&&!Left(Qp[r-1],S[i]))--r;
while(l<r&&!Left(Qp[l],S[i]))++l;
if(zero(cross(Q[r].v,S[i].v))==0)
Q[r]=Left(Q[r].p,S[i])?Q[r]:S[i];
else Q[++r]=S[i];
if(l<r)Qp[r-1]=Intersection(Q[r],Q[r-1]);
}
while(l<r&&!Left(Qp[r-1],Q[l]))--r;
return (r-l)>1;
}
int main()
{
n=read();
for(int i=0;i<n;++i)p[i].x=read(),p[i].y=read();p[n]=p[0];
for(int i=0;i<n;++i)S[++tot]=(Line){p[i],p[i+1]-p[i]};
for(int i=1;i<n;++i)area+=fabs(cross(p[i]-p[0],p[i+1]-p[0]));
for(int i=1;i<n;++i)
{
double a=p[0].y-p[1].y-p[i].y+p[i+1].y;
double b=-p[0].x+p[1].x+p[i].x-p[i+1].x;
double c=cross(p[0],p[1])-cross(p[i],p[i+1]);
Line d;
if(fabs(a)>eps)d=(Line){(Node){-c/a,0},(Node){-b,a}};
else d=(Line){(Node){0,-c/b},(Node){-b,a}};
S[++tot]=d;
}
HalfPlaneIntersection();
double ans=0;Qp[r]=Intersection(Q[l],Q[r]);
for(int i=l+1;i<r;++i)ans+=fabs(cross(Qp[i]-Qp[l],Qp[i+1]-Qp[l]));
printf("%.4lf\n",ans/area);
return 0;
}

【BZOJ4445】[SCOI2015]小凸想跑步(半平面交)的更多相关文章

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

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

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

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=4445 题解: 设点坐标,利用叉积可以解出当p坐标为\((x_p,y_p)\)时,与边i- ...

  3. bzoj 4445 小凸想跑步 - 半平面交

    题目传送门 vjudge的快速通道 bzoj的快速通道 题目大意 问在一个凸多边形内找一个点,连接这个点和所有顶点,使得与0号顶点,1号顶点构成的三角形是最小的概率. 假设点的位置是$(x, y)$, ...

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

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

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

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

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

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

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

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

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

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

  9. [SCOI2015]小凸想跑步

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

随机推荐

  1. impress.js初体验——前端装X利器

    impress.js 是国外一位开发者受 Prezi 启发,采用 CSS3 与 JavaScript 语言完成的一个可供开发者使用的表现层框架(演示工具).其功能包括画布的无限旋转与缩放,任意角度放置 ...

  2. Java的初始化与清理

    大家都知道,Java是站在巨人的肩上成功的,它是在C&C++的基础上进一步的开发,投入面向对象开发的怀抱.Java吸取了很多以前的教训,加入自己很多独创的方式.在程序语言发展初期,许多C程序员 ...

  3. LightOJ 1027 A Dangerous Maze(期望)

    https://cn.vjudge.net/problem/LightOJ-1027 题意:有n扇门,每扇门有个时间ti,选择正数的门可以在ti后带你走出迷宫,负数的门会在ti后带你回到起点,然后重新 ...

  4. java学习之浅谈多线程4--SwingWorker

    GUI事件处理和绘图代码在一个被称为事件分发线程的特殊线程中执行.如果一个事件需要很长的时间处理,线程就不能顾及到队列中的其他任务.为了解决这个问题,可以运行费时的任务来处理单独线程中的事件.Swin ...

  5. 日志_测试代码_Delphi7

    1. 2.Delphi (Windows API 文件尾部添加) function LogFile(_str :string) :integer; var hFile :THandle; strFil ...

  6. 递归--练习10--noi1696逆波兰表达式

    递归--练习10--noi1696逆波兰表达式 一.心得 递归大法好 二.题目 1696:逆波兰表达式 总时间限制:  1000ms 内存限制:  65536kB 描述 逆波兰表达式是一种把运算符前置 ...

  7. 递归--练习9--noi8758 2的幂次方表示

    递归--练习9--noi8758 2的幂次方表示 一.心得 找准子问题就好 二.题目 8758:2的幂次方表示 总时间限制:  1000ms 内存限制:  65536kB 描述 任何一个正整数都可以用 ...

  8. 简单的spring mvc实例

    简单的springmvc实例 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&qu ...

  9. Rails-Treasure chest3 嵌套表单; Ransack(3900✨)用于模糊查询, ranked-model(800🌟)自订列表顺序; PaperTrail(5000✨)跟踪model's data,auditing and versioning.

    自订列表顺序, gem 'ranked-model' 多步骤表单 显示资料验证错误讯息 资料筛选和搜寻, gem 'ransack' (3900✨); 软删除和版本控制 数据汇出(csv), 自订列表 ...

  10. Confluence 6 创建一个用户宏

    如果你想创建自定义的宏的话,用户宏能够帮你完成这个任务.这个可以在你系统中应用特定的操作,比如说应用自定义格式等. 用户用是在 Confluence 创建和和管理的,你需要有一定的编码基础才可以. 你 ...