小凸想跑步
来源:互联网 发布:食品生产许可证淘宝 编辑:程序博客网 时间:2024/05/17 03:13
小凸想跑步
时间限制: 1 Sec 内存限制: 128 MB
题目描述
小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏。
操场是个凸n边形,n个顶点按照逆时针从0 ~ n-1编号。现在小凸随机站在操场的某个位置,标记为p点。将p点与n个顶点各连一条边,形成n个三角形。如果这时p点,0号点,1号点形成的三角形的面积是n个三角形中最小的一个,小凸则认为这是一次正确站位。
现在小凸想知道他一次站位正确的概率是多少。
输入
第1行包含1个整数n,表示操场的顶点数和游戏的次数。
接下来有n行,每行包含2个整数xi,yi,表示顶点的坐标。
输入保证按逆时针顺序输入点,所有点保证构成一个凸多边形。所有点保证不存在三点共线。
输出
输出1个数,正确站位的概率,保留4个小数。
样例输入
5
1 8
0 7
0 0
8 0
8 8
样例输出
0.6316
数据范围
对于30%的数据,3≤n≤4,0≤x,y≤10
对于100%的数据,3≤n≤105,-109≤x,y≤109
来源
SCOI 2015 Day1
题解
对于每一条边,我们可以解一个不等式得到以它为底的三角形面积大于以01号点连边为底的三角形的范围,由此可以得到N个半平面,然后求半平面角即可。
代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<cmath>#include<algorithm>#define N 100010#define eps 1e-7using namespace std;int n,tot;double ans1,ans2;struct point{ double x,y; point operator+(const point &p) const{return (point){x+p.x,y+p.y};} point operator-(const point &p) const{return (point){x-p.x,y-p.y};} point operator*(const double &num) const{return (point){x*num,y*num};} double operator^(const point &p) const{return x*p.y-p.x*y;}}t[N],p[N*2];struct node{ point p,v;double ang; bool operator<(const node &x) const{return ang<x.ang||(ang==x.ang&&(v^(x.p-p))<eps);}}s[N*2],q[N*2];bool pd(node a,point b){return (a.v^(b-a.p))<-eps;}double get_ang(point p){return atan2(p.y,p.x);}point get_jd(node a,node b){ point x=a.p-b.p; double t=(b.v^x)/(a.v^b.v); return a.p+a.v*t;}void solve(){ sort(s+1,s+n+1);tot=1; for(int i=2;i<=n;i++) if(fabs(s[i].ang-s[i-1].ang)>eps)s[++tot]=s[i]; int l=1,r=2;q[1]=s[1];q[2]=s[2];n=tot; for(int i=3;i<=n;i++) { while(l<r&&pd(s[i],get_jd(q[r],q[r-1])))r--; while(l<r&&pd(s[i],get_jd(q[l],q[l+1])))l++; q[++r]=s[i]; } while(l<r&&pd(q[l],get_jd(q[r],q[r-1])))r--; while(l<r&&pd(q[r],get_jd(q[l],q[l+1])))l++; if(r-l<=1)return; q[r+1]=q[l];tot=0; for(int i=l;i<=r;i++)p[++tot]=get_jd(q[i],q[i+1]); p[tot+1]=p[1]; for(int i=1;i<=tot;i++)ans2+=fabs((p[i]-p[1])^(p[i+1]-p[1]));}void prepare(){ double X1=t[1].x,Y1=t[1].y; double X2=t[2].x,Y2=t[2].y; for(int i=2;i<=n;i++) { double X3=t[i].x,Y3=t[i].y; double X4=t[i+1].x,Y4=t[i+1].y; double a=Y1-Y2-Y3+Y4,b=X2-X1-X4+X3; double c=X3*Y4-X4*Y3+X2*Y1-X1*Y2; double p1,p2,p3,p4; if(fabs(a)<eps){p1=0,p2=c/b,p3=1,p4=c/b;if(b>0)swap(p1,p3),swap(p2,p4);} else if(fabs(b)<eps){p1=c/a,p2=0,p3=c/a,p4=1;if(a<0)swap(p1,p3),swap(p2,p4);} else if(b<0)p1=0,p2=c/b,p3=1,p4=c/b-a/b; else p1=1,p2=c/b-a/b,p3=0,p4=c/b; point X1=(point){p1,p2},X2=(point){p3-p1,p4-p2}; s[i]=(node){X1,X2,get_ang(X2)}; } s[1]=(node){t[1],t[2]-t[1],get_ang(t[2]-t[1])};} int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf",&t[i].x,&t[i].y);t[n+1]=t[1]; for(int i=1;i<=n;i++)ans1+=((t[i]-t[1])^(t[i+1]-t[1])); prepare();solve(); printf("%.4lf",ans2/ans1); return 0;}
0 0
- 小凸想跑步
- scoiday1T3&&bzoj4445小凸想跑步
- scoi2015小凸想跑步
- 4445: [Scoi2015]小凸想跑步
- [bzoj4445] [Scoi2015]小凸想跑步
- bzoj4445: [Scoi2015]小凸想跑步
- 跑步
- 跑步
- 跑步
- 跑步
- 跑步
- 跑步
- 跑步
- 跑步
- 跑步
- 跑步
- 跑步
- 跑步
- Apache Hadoop 安装
- Java进阶(二十)解疑答惑之何时字符串才算真正为空?
- 网络编程
- Coin change
- Sicily 1134. 积木分发
- 小凸想跑步
- [code segments] OpenCV3.0 SVM with C++ interface
- 文件操作
- 数据库Oracle知识整理
- C++ map和set中的结构体
- Java语言程序设计-总结
- 不再以讹传讹,GET和POST的真正区别
- 第二章.管理数据库和表.总结
- java学习:有关DataInputStream/DataOutputStream的一些坑