codeforces 681E - Runaway to a Shadow 计算几何
来源:互联网 发布:天下3帅气男号捏脸数据 编辑:程序博客网 时间:2024/05/21 17:42
题意: 一只小强速度为v,若在T的时间内不能移动到n个半径为r的圆形掩蔽物的其中一个之下,就会被打死。他的移动策略是随机选一个方向移动,如果进入掩蔽物下就停止移动。问他存活的几率?
分析: 这题的几何意义不难想到,对于其中以小强为圆心的圆,求它与每个遮蔽圆相重叠的角度,最后将所有重叠的角度合并起来除以2*PI就是结果。
要注意判断圆的几种位置关系,相离直接跳过,如果圆心距小于小圆半径答案直接输出1.00000。然后当圆心距<sqrt(R^2+r^2) 此时直接用asin函数算出1/2圆心角,不然的话就是普通的相交,相交用acos加上余弦公式算出1/2圆心角。
每个角度用两个向量来保存,存入一个容器中,注意如果角度跨界了(小于0or大于2*PI)要把一个角度分解成两个。
最后用类似扫描线的算法合并所有角度,所以每个角度的两个向量存入容器时都要附带一个象征起点(终点)的1(-1).
还有就是这题不管如何优化cin,cout都要超时,但是我实在搞不清mingw的long double到底怎么用cstdio的函数输入输出,最终只能输入读成lld再变成long double输出用cout。
AC代码:
#include <iostream>#include <cmath>#include <algorithm>#include <vector>#include <cstdio>#include <iomanip>using namespace std;#define PI 3.1414159265358struct Point { long double x, y; Point (long double x=0, long double y=0):x(x),y(y){}};typedef Point Vector;const long double eps =1e-10;int dcmp(long double x){ if(fabs(x)<eps ) return 0; return x<0?-1:1;}long double Dot(Vector A,Vector B) { return A.x*B.x +A.y*B.y;}long double Length(Vector A){return sqrt(Dot(A,A));}//4.2struct Circle { Point c; long double r; Point point(long double a) {//极坐标转平面坐标 return Point(c.x +cos(a)*r,c.y+sin(a)*r); }};long double angle(Vector v) { return atan2(v.y, v.x);}long double X0,Y0,v,T,R;bool flag;vector<pair<long double,int> > vp;void solve(Circle& c){ long double dis=Length(Point(c.c.x-X0,c.c.y-Y0)); if(dcmp(dis-c.r)<=0){ flag=1;return;} if(dcmp(dis-R-c.r)>0)return; //计算极角 long double ang0=atan2(c.c.x-X0,c.c.y-Y0);//special if(dcmp(ang0)<0) ang0+=2*PI; //计算交点与圆心连线与圆心间连线所成角 long double dd=sqrt(dis*dis-c.r*c.r); long double ang; if(dcmp(R-dd)>=0) ang=asin(c.r/dis); else ang=acos((R*R+dis*dis-c.r*c.r)/(2.0*dis*R)); long double ang1=ang0-ang, ang2=ang0+ang; if(dcmp(ang1)<0){//分解跨界角 ang1+=2*PI; vp.push_back(make_pair(ang1,1)); vp.push_back(make_pair(2*PI,-1)); vp.push_back(make_pair(0.0,1)); vp.push_back(make_pair(ang2,-1)); } else if(dcmp(ang2-2*PI)>0){//ang2与ang1差距不超过PI,故ang1>PI ang2-=2*PI; vp.push_back(make_pair(ang1,1)); vp.push_back(make_pair(2*PI,-1)); vp.push_back(make_pair(0.0,1)); vp.push_back(make_pair(ang2,-1)); } else { vp.push_back(make_pair(ang1,1)); vp.push_back(make_pair(ang2,-1)); }}int main(){ cin>>X0>>Y0>>v>>T; R=v*T; int n; cin>>n; flag=0; while(n--){ Circle c; int xx,yy,rr; scanf("%d%d%d",&xx,&yy,&rr); c.c.x=xx*1.0; c.c.y=yy*1.0; c.r=rr*1.0; solve(c); if(flag){ cout<<fixed<<setprecision(5)<<1.000<<endl; return 0; } } sort(vp.begin(),vp.end()); int now=0,last=0,tmp=0; long double ans=0.0; for(int i=0;i<vp.size();i++){ now=i; tmp+=vp[i].second; if(tmp==0){ ans+=vp[now].first-vp[last].first; last=now+1;//到now为止构成一个完整的概率区间,下一个起点为now+1. } } cout<<setprecision(5)<<(ans/(2*PI))<<endl; return 0;}
0 0
- codeforces 681E - Runaway to a Shadow 计算几何
- Codeforces Round #357 (Div. 2) E. Runaway to a Shadow 计算几何
- 7.15 J codeforces 681E Runaway to a Shadow
- Codeforces Round #357 (Div. 2) E. Runaway to a Shadow
- [Codeforces Round #357 DIV2E (CF681E)] Runaway to a Shadow
- Codeforces 682E 计算几何
- CodeForces-77E(计算几何+笛卡尔定理)
- codeforces 223E 计算几何 图论 网络流思想
- CodeForces 274C|275E|The Last Hole!|计算几何
- Codeforces Round #357 (Div. 2) E 计算几何
- CodeForces 682 E.Alyona and Triangles(计算几何)
- CodeForces 498A-Crazy Town-简单计算几何
- CodeForces 630 P. Area of a Star(计算几何)
- CodeForces 613 A. Peter and Snow Blower(计算几何)
- CodeForces P. Area of a Star【计算几何】
- Codeforces 140 A. New Year Table(计算几何)
- Codeforces 32E Hide-and-Seek 求2点关于镜面反射 计算几何
- Codeforces Round #358 (Div. 2) E 计算几何 旋转卡壳求最大三角形面积
- jzoj 1384. 【2012.02.18普及组】上学路线
- Android项目开发错误锦集-9patchPng报错
- 编程与高等数学?
- 同步到网络时间服务器
- 最小生成树(prime)
- codeforces 681E - Runaway to a Shadow 计算几何
- Ubuntu常用工具安装
- SQL语言——基础语言:查询、增、删、改
- Mysql的varchar排序按照数字顺序
- hdu2035-求N^N的后三位
- MYSQL数据库操作类
- 在宇宙间不易被风吹散 —— 银河系
- 最轻的天平 (Standard IO)
- Java 操作Oracle数据库(建表,插数据,删除)