4445: [Scoi2015]小凸想跑步 半平面交
题目大意:
题解:
设点坐标,利用叉积可以解出当p坐标为\((x_p,y_p)\)时,与边i--(i+1)构成的三角形面积为
\]
我们又知道三角形\(0 -- 1 -- (p)\)是最小的,所以我们列出不等式后移项变号得
\]
我们发现这是一个\(ax^2 + bx + c < 0\)的形式
所以我们就可以使用数学上的线性规划来解决问题
当然在OI里就可以写半平面交了
不要忘记还应限制这个点在多边形中.
Code
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 110010;
const double eps = 1e-9;
inline int dcmp(const double &x){
if(x < eps && x > -eps) return 0;
return x > 0 ? 1 : -1;
}
struct Point{
double x,y;
Point(){}
Point(const double &a,const double &b){
x=a;y=b;
}
};
typedef Point Vector;
Vector operator + (const Vector &a,const Vector &b){
return Vector(a.x+b.x,a.y+b.y);
}
Vector operator - (const Vector &a,const Vector &b){
return Vector(a.x-b.x,a.y-b.y);
}
Vector operator * (const Vector &a,const double &b){
return Vector(a.x*b,a.y*b);
}
double cross(const Vector &a,const Vector &b){
return a.x*b.y - a.y*b.x;
}
struct line{
Point p;
Vector v;
double alpha;
line(){}
line(const Point &a,const Point &b){
p = a;v = b;
alpha = atan2(v.y,v.x);
}
};
inline bool cmp(const line &a,const line &b){
return a.alpha < b.alpha;
}
inline Point lineInterion(const line &l1,const line &l2){
Vector u = l1.p - l2.p;
double t = cross(l2.v,u)/cross(l1.v,l2.v);
return l1.p + l1.v*t;
}
inline bool onLeft(const Point &p,const line &l){
return dcmp(cross(l.v,p-l.p)) > 0;
}
line lines[maxn<<2],q[maxn<<2];
Point p[maxn<<2];int l,r;
inline bool halfInterion(int n){
sort(lines+1,lines+n+1,cmp);
l = r = 1;q[1] = lines[1];
for(int i=2;i<=n;++i){
while(l < r && !onLeft(p[r-1],lines[i])) -- r;
while(l < r && !onLeft(p[l],lines[i]) ) ++ l;
if(dcmp(cross(q[r].v,lines[i].v)) == 0)
q[r] = onLeft(q[r].p,lines[i]) ? q[r] : lines[i];
else q[++r] = lines[i];
if(l < r) p[r-1] = lineInterion(q[r],q[r-1]);
}
while(l < r && !onLeft(p[r-1],q[l])) -- r;
return (r-l) > 1;
}
double x[maxn],y[maxn];
int main(){
int n;read(n);
int cnt = 0;
double total = .0;
for(int i=0;i<n;++i){
scanf("%lf%lf",&x[i],&y[i]);
}x[n] = x[0];y[n] = y[0];
for(int i=0;i<n;++i){
lines[++cnt] = line(Point(x[i],y[i]),Vector(x[i+1]-x[i],y[i+1]-y[i]));
}
for(int i=1;i<n-1;++i){
total += abs(cross(Point(x[i]-x[0],y[i]-y[0]),Point(x[i+1]-x[0],y[i+1]-y[0])));
}
for(int i=1;i<n;++i){
double a = y[0] - y[1] - y[i] + y[i+1];
double b = x[1] - x[0] - x[i+1] + x[i];
double c = x[0]*y[1] - x[1]*y[0] - x[i]*y[i+1] + x[i+1]*y[i];
Point p,v(-b,a);
if(dcmp(b) == 0) p = Point(-c/a,0.0);
else p = Point(0.0,-c/b);
lines[++cnt] = line(p,v);
}
bool flag = halfInterion(cnt);
if(!flag) return puts("0.000");
double ans = .0;p[r] = lineInterion(q[l],q[r]);
for(int i=l+1;i<r;++i){
ans += abs(cross(p[i]-p[l],p[i+1]-p[l]));
}
printf("%.4lf\n",ans/total);
getchar();getchar();
return 0;
}
4445: [Scoi2015]小凸想跑步 半平面交的更多相关文章
- 【BZOJ4445】[Scoi2015]小凸想跑步 半平面交
[BZOJ4445][Scoi2015]小凸想跑步 Description 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸n边形,N个顶点按照逆时针从0-n-l编号.现 ...
- bzoj 4445 小凸想跑步 - 半平面交
题目传送门 vjudge的快速通道 bzoj的快速通道 题目大意 问在一个凸多边形内找一个点,连接这个点和所有顶点,使得与0号顶点,1号顶点构成的三角形是最小的概率. 假设点的位置是$(x, y)$, ...
- BZOJ 4445 [Scoi2015]小凸想跑步:半平面交
传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...
- bzoj 4445 [SCOI2015] 小凸想跑步
题目大意:一个凸包,随机一个点使得其与前两个点组成的面积比与其他相邻两个点组成的面积小的概率 根据题意列方程,最后求n条直线的交的面积与原凸包面积的比值 #include<bits/stdc++ ...
- 【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 ...
- BZOJ4445: [Scoi2015]小凸想跑步
裸半平面交. 记得把P0P1表示的半平面加进去,否则点可能在多边形外. #include<bits/stdc++.h> #define N 100009 using namespace s ...
- [bzoj4445] [SCOI2015]小凸想跑步 (半平面交)
题意:凸包上一个点\(p\),使得\(p\)和点\(0,1\)组成的三角形面积最小 用叉积来求: \(p,i,i+1\)组成的三角形面积为: (\(\times\)为叉积) \((p_p-i)\tim ...
- 【LuoguP4081】[SCOI2015]小凸想跑步
题目链接 题意 给你一个凸多边形,求出在其内部选择一个点,这个点与最开始输入的两个点形成的三角形是以该点对凸多边形三角剖分的三角形中面积最小的一个三角形的概率. Sol 答案就是 可行域面积与该凸多边 ...
随机推荐
- MySQL 下 ROW_NUMBER / DENSE_RANK / RANK 的实现
原文链接:http://hi.baidu.com/wangzhiqing999/item/7ca215d8ec9823ee785daa2b MySQL 下 ROW_NUMBER / DENSE_RAN ...
- Ajax 中的高级请求和响应
一.概述 在本文中,重点介绍这个请求对象的 3 个关键部分的内容: 1.HTTP 就绪状态 2.HTTP 状态代码 3.可以生成的请求类型 这三部分内容都是在构造一个请求时所要考虑的因素:但是介绍这些 ...
- But what exactly do we mean by "gets closer to"?
https://rdipietro.github.io/friendly-intro-to-cross-entropy-loss/ [将输入转化为输出:概率分布] When we develop a ...
- jQuery-AJAX-格式
function loadInfo(){ var domainName=$("input[name='domain-name']").val(); //域名 var c ...
- Android代码绘制虚线、圆角、渐变效果图
drawable文件夹放置动画/形状/选择器等属性文件,唯一的drawable文件名,不允许写错和拼错,否则运行报错.drawable文件夹底下的xml文件可以包括的标签共18个:animation- ...
- php生成随机密码的自定义函数
php生成随机密码的自定义函数 生成一个随机密码的函数,生成的密码为小写字母与数字的随机字符串,长度可自定义. 复制代码代码如下: <?php /* * php自动生成新密码自定义函数(带实例 ...
- 什么是gevent
gevent是一个基于协程的python网络库,它使用greenlet在libev或libuv事件循环之上提供高级同步API 功能包括 基于libev或libuv的快速时间循环 基于greenlets ...
- 小程序真机GET请求出现406错误
问题:微信开发模拟器请求成功,获得数据,但是在真机上出现406请求错误,无法获得请求结果 原因:真机微信小程序的请求头与模拟器不同 怎么发现的:在请求头强制添加Accept即可解决 修复:在请求Hea ...
- Ubuntu下,grep的用法
grep(Global search Regular Expression and Print out the line)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.U ...
- 2014年互联网IT待遇
1. 13k*14~16k*145.美团 13k*15~16k*15,也有更高的.6.去哪儿 11k*16~15k*167.人人技术类(12K-14K)*14 (2014)8.58同城 20w+9.网 ...