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 答案就是 可行域面积与该凸多边 ...
随机推荐
- 大组合取模之:1<=n<=m<=1e6,1<=p<=1e9
/****************************** 大组合取模之:1<=n<=m<=1e6,1<=p<=1e9 使用:程序最开始调用getprime(),需要 ...
- 白昼夢 / Daydream(模拟)
C - 白昼夢 / Daydream Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement You ...
- 【JavaScript专题】--- 立即执行函数表达式
一 什么是立即执行函数表达式 立即执行函数表达式,其实也可以叫初始化函数表达式,英文名:IIFE,immediately-inovked-function expression.立即执行函数表达式就是 ...
- windows7下cmd命令窗口没有滚动条的解救方法
由于昨天的好123问题没有解决,我想查看一下本机的ip地址等,于是打开了cmd窗口,输入ipconfig/all命令进行查看,但是发现出现了下面的窗口,无法进行滚动,完全无法查看详细的信息. 然后我百 ...
- Excel 文件下载
INCLUDE OLE2INCL * ALV输出 CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' EXPORTING I_CALLBACK_PRO ...
- JavaScript螺旋矩阵
螺旋矩阵 螺旋矩阵指一个呈螺旋状的矩阵,其数字由第一行开始到右边不断变大,向下变大, ...
- 深度问答之提取语料,导入了yml模块
根据目录下的yml文件循环创建同名文件夹,并从yml文件读取问答并给每个文件夹写入question和answer文件 #!/usr/bin/env python # coding:utf8 # aut ...
- rails 常用方法
bundle install --without production 不安装production中的gem ./configure && make && sudo m ...
- Thread.currentThread().getContextClassLoader() and Class.getClassLoader()
Thread.currentThread().getContextClassLoader() and Class.getClassLoader() 一.同一工程中: String path = T ...
- Data Structure Array: Maximum circular subarray sum
http://www.geeksforgeeks.org/maximum-contiguous-circular-sum/ #include <iostream> #include < ...