Codeforces Round #125 div1 C Delivering Carcinogen

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove

题目:行星围绕着恒星转,飞船用最少的时间抵达行星上,不能距离恒星太近,问最少时间。

二分答案,然后可以算出行星的末位置,计算出飞船到目标位置的最短距离,判断一下最短距离是否小于飞船的速度乘以时间。

其中最短距离分为两种情况,可以是直线,可能是两条切线+一段弧。

其中那段弧的圆心角是先计算出两点之间的夹角,然后减去两个直角三角形的内角。

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<string>
#include<vector>
#define eps 1e-10
#define LL long long
#define LD long double
#define pi acos(-1.0)
using namespace std;
struct Point{
	LD x,y;
}per,qwe,goal,central;
LD v,vp,r,R,ang;
LD Dist(Point p1,Point p2){
	return (LD)sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
LD slove(LD t){
	LD angle=(ang+t*vp/R);   //目标位置的角度
	goal.x=R*cos(angle),goal.y=R*sin(angle);     //目标位置坐标
	//cout<<goal.x<<" "<<goal.y<<endl;
	LD qiexian1=sqrt(qwe.x*qwe.x+qwe.y*qwe.y-r*r);   //起始位置与恒星安全区的切线长度
	LD qiexian2=sqrt(goal.x*goal.x+goal.y*goal.y-r*r);    //目标位置与恒星安全区的切线长度
	LD dist=Dist(qwe,goal);      //起始位置与目标位置之间的距离
	if(dist<qiexian2+qiexian1)  { //从起始位置到目标位置的直线与安全区不相交
	//	cout<<dist<<endl;
		return dist;
	}
	else{		
		LD dist1=Dist(qwe,central);
		LD dist2=Dist(goal,central);
		LD centralangle=acos((dist1*dist1+dist2*dist2-dist*dist)/(2*dist1*dist2))-atan(qiexian1/r)-atan(qiexian2/r); //扇形的圆心角
	//	cout<<centralangle*r+qiexian1+qiexian2<<endl;
		return centralangle*r+qiexian1+qiexian2;
	}
}
int main(){
	central.x=central.y=0;
	while(scanf("%lf%lf%lf%lf%lf%lf%lf",&per.x,&per.y,&vp,&qwe.x,&qwe.y,&v,&r)!=EOF){
		ang=atan2(per.y,per.x);   //行星初始角度
		R=sqrt(per.x*per.x+per.y*per.y);     //行星轨迹半径
		LD high=1000000,low=0,mid;
		while(high-low>eps){
			mid=(low+high)/2;
			if(slove(mid)<=eps+mid*v)
				high=mid;
			else
				low=mid;
		}
		printf("%.10f\n",mid);
	}
	return 0;
}
/*
10 0 1
-10 0 2 8
50 60 10
50 60 20 40
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值