题面

题解

推波柿子:

设点\(A(x_a, y_a), B(x_b, y_b), C(x_c, y_c), D(x_d, y_d), P(x, y)\)

\(\vec{a} = (x_b - x_a, y_b - y_a), \vec{b} = (x_d - x_c, y_d - y_c)\)

\(\overrightarrow{AP} = (x - x_a, y - y_a), \overrightarrow{CP} = (x - x_c, y - y_c)\)

\(\vec{a} \times \overrightarrow{AP} = (x_b - x_a)(y - y_a) - (x_b - y_a)(x - x_a)\)

\(\vec{b} \times \overrightarrow{CP} = (x_d - x_c)(y - y_c) - (y_d - y_c)(x - x_c)\)

由题目,\(\vec{a} \times \overrightarrow{AP} < \vec{b} \times \overrightarrow{CP}\),那么有

\[\begin{aligned}
&(x_b - x_a)(y - y_a) - (x_b - y_a)(x - x_a) < (x_d - x_c)(y - y_c) - (y_d - y_c)(x - x_c) \\
\Rightarrow & (x_b - x_a + x_d - x_c)y - (y_b - y_a - y_d + y_c)x + (y_b x_a - x_b y_a + y_d x_c - x_d y_c) < 0
\end{aligned}
\]

然后这个就是一个裸的半平面交了。

代码

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#define RG register
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define clear(x, y) memset(x, y, sizeof(x)) inline int read()
{
int data = 0, w = 1; char ch = getchar();
while(ch != '-' && (!isdigit(ch))) ch = getchar();
if(ch == '-') w = -1, ch = getchar();
while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
} const int maxn(200010);
struct point { double x, y; } p[maxn];
struct line { point x, y; double ang; } L[maxn];
typedef point vector; inline vector operator + (const vector &lhs, const vector &rhs)
{ return (vector) {lhs.x + rhs.x, lhs.y + rhs.y}; }
inline vector operator - (const vector &lhs, const vector &rhs)
{ return (vector) {lhs.x - rhs.x, lhs.y - rhs.y}; }
inline vector operator * (const vector &lhs, const double &rhs)
{ return (vector) {lhs.x * rhs, lhs.y * rhs}; }
inline double operator * (const vector &lhs, const vector &rhs)
{ return lhs.x * rhs.x + lhs.y * rhs.y; }
inline double cross(const vector &lhs, const vector &rhs)
{ return lhs.x * rhs.y - lhs.y * rhs.x; }
inline line make_line(const point &x, const point &y)
{ return (line) {x, y, atan2(y.y, y.x)}; }
inline bool operator < (const line &lhs, const line &rhs)
{ return lhs.ang < rhs.ang; }
inline bool isLeft(const point &a, const line &b)
{ return cross(b.y, (a - b.x)) > 0; }
point Intersection(const line &a, const line &b)
{ return a.x + a.y * (cross(b.y, b.x - a.x) / cross(b.y, a.y)); } int n, m;
double Area, ans; void HalfPlane()
{
int l, r = 1; std::sort(L + 1, L + m + 1);
for(RG int i = 2; i <= m; i++)
if(L[i].ang != L[r].ang) L[++r] = L[i];
else if(isLeft(L[i].x, L[r])) L[r] = L[i];
m = r, l = r = 1;
for(RG int i = 2; i <= m; i++)
{
while(l < r && !isLeft(p[r], L[i])) --r;
while(l < r && !isLeft(p[l + 1], L[i])) ++l;
L[++r] = L[i];
if(l < r) p[r] = Intersection(L[r], L[r - 1]);
}
while(l < r && !isLeft(p[r], L[l])) --r;
p[l] = p[r + 1] = Intersection(L[r], L[l]);
for(RG int i = l; i <= r; i++) ans += cross(p[i], p[i + 1]);
ans /= Area;
} int main()
{
n = read();
for(RG int i = 0; i < n; i++)
p[i] = (point) {(double)read(), (double)read()};
p[n] = p[0];
for(RG int i = 0; i < n; i++)
L[++m] = make_line(p[i], p[i + 1] - p[i]),
Area += cross(p[i], p[i + 1]);
for(RG int i = 1; i < n; i++)
{
double a = p[1].x - p[0].x + p[i].x - p[i + 1].x;
double b = p[1].y - p[0].y + p[i].y - p[i + 1].y;
double c = p[1].x * p[0].y + p[i].x * p[i + 1].y
- p[0].x * p[1].y - p[i + 1].x * p[i].y;
if(a) L[++m] = make_line((point) {0, c / a}, (point) {-a, -b});
else if(b) L[++m] = make_line((point) {-c / b, 0}, (point) {0, -b});
}
HalfPlane();
printf("%.4lf\n", ans);
return 0;
}

【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]小凸想跑步(半平面交)

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

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

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

随机推荐

  1. Android事件总线(一)EventBus3.0用法全解析

    前言 EventBus是一款针对Android优化的发布/订阅事件总线.简化了应用程序内各组件间.组件与后台线程间的通信.优点是开销小,代码更优雅,以及将发送者和接收者解耦.如果Activity和Ac ...

  2. 【Python】keras使用LSTM拟合曲线

    keras生成的网络结构如下图: 代码如下: from sklearn.preprocessing import MinMaxScaler from keras.models import Seque ...

  3. LeetCode题解之Binary Tree Level Order Traversal II

    1.题目描述 2.题目分析 先遍历,再反转. 3.代码 vector<vector<int>> levelOrderBottom(TreeNode* root) { vecto ...

  4. EF的CodeFirst模式自动迁移(适用于开发环境)

    EF的CodeFirst模式自动迁移(适用于开发环境) 1.开启EF数据迁移功能 NuGet包管理器------>程序包管理控制台---------->Enable-Migrations ...

  5. 简单易懂的程序语言入门小册子(1):基于文本替换的解释器,lambda演算

    最近比较闲,打算整理一下之前学习的关于程序语言的知识.主要的内容其实就是一边设计程序语言一边写解释器实现它.这些知识基本上来自Programming Languages and Lambda Calc ...

  6. https://www.testingcircus.com/tell-me-about-yourself-6-sample-answers-software-testers/

    https://www.testingcircus.com/tell-me-about-yourself-6-sample-answers-software-testers/ Tell Me Abou ...

  7. selenium+python自动化笔记之一

    一.webdriver的API与定位元素 元素定位核心部分 元素名称 webdriver API 说明 id find_element_by_id() id定位 name find_element_b ...

  8. nginx基础知识总结

    1.nginx的工作模式 master/worker工作模式: 一个master进程: 负载加载和分析配置文件.管理worker进程.平滑重启升级等. 一个或多个worker进程 处理并响应用户请求 ...

  9. Linux防火墙基础与编写防火墙规则

    Iptables采用了表和链的分层结构,每个规则表相当于内核空间的一个容器,根据规则集的不同用途划分为默认的四个表,raw表,mangle表,nat表,filter表,每个表容器内包括不同的规则链,根 ...

  10. mysql状态分析之show global status(转)

    mysql> show global status;可以列出MySQL服务器运行各种状态值,我个人较喜欢的用法是show status like '查询值%';一.慢查询mysql> sh ...