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 答案就是 可行域面积与该凸多边 ...
随机推荐
- ASIHTTP 框架,同步、 异步请求、 上传 、 下载
ASIHTTPRequest详解 ASIHTTPRequest 是一款极其强劲的 HTTP 访问开源项目.让简单的 API 完成复杂的功能,如:异步请求,队列请求,GZIP 压缩,缓存,断点续传,进度 ...
- apple-touch-icon-precomposed 和 apple-touch-icon属性区别
苹果safari浏览器当中apple-touch-icon-precomposed 和 apple-touch-icon属性是有区别的,之前在网上查了下相关的资料和苹果的开发文档手册,对这两中属性区别 ...
- Java Enum 比较用 == 还是 eques
我是把枚举当作常量来使用的,枚举中还有两个自己的属性,关注到这个地方的朋友对枚举已经有了认识,这里就不再编写枚举的demo了,这里我直接说结果吧,在枚举中使用==和equals比较效果是一样的,查看源 ...
- Full卷积 Same卷积 Vaild卷积
- mysql 自连接查询数据
今天项目BOSS提了个sql语句需求,我听得稀里糊涂,没办法,一步步讨论.实践,最终搞定. 先上建表语句: /* Navicat MySQL Data Transfer Source Server : ...
- 提供的STC89C52RC单片机GPS在LCD1602液晶只显示welcome to use问题?
1.使用USB-TTL接GPS单独测试GPS定位在所处环境看是否能定位到. 2.检查自己使用的单片机是不是STC89C52RC型号,提供例程使用的这个型号单片机.如果使用其他51单片机,请先使用STC ...
- 关于Unicode转为str的方法
unicode_a=u'\u810f\u4e71' str_a=unicode_a.encode('unicode-escape').decode('string_escape')
- 改善程序与设计的55个具体做法 day2
条款05:了解C++默默编写并调用哪些函数 如果没有为类定义构造函数.析构函数.拷贝构造函数.重载赋值操作符,并且这些函数被需要(调用)时,编译器会为类生成默认的函数,而这些函数是public inl ...
- [转]Mysql命令
1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...
- Python 3 并发编程多进程之守护进程
Python 3 并发编程多进程之守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemo ...