The 2019 ACM-ICPC China Shannxi Provincial Programming Contest C.Angel's Journey(计算几何基础)

题目

T(T<=500)组样例,每组样例给出rx,ry,r,x,y(-100<=rx,ry,x,y<=100,0<r<=100)

代表被救的人在(rx,ry-r)位置,且(rx,ry)为圆心有一个半径为r的圆

你从圆外(x,y)出发,题目保证y>ry,

y=ry及这条水平线以下的圆外部分是海,圆内部也是海,都不能经过

问(x,y)到(rx,ry-r)的最短距离

思路来源

归神代码

题解

记A(x,y),O(rx,ry),S(rx,ry-r),D(rx+r,ry),E(rx-r,ry)

过A的直线与圆的切点F,坐标未知

考虑棕色边的三角形AOS,余弦定理求顶角AOS,

余弦定理求直角三角形AFO的角AOF,作差得角FOS

①角FOS小于90度,说明FOS在海里,不可通过直线达,取点E和点D的较近点,再走1/4弧

②角FOS大于90度,FOS可以通过与切点的线段到达,再走圆上一段弧即可

这种判断,省去了对两个切点的分别判断,感觉比较巧妙吖

代码

#include<bits/stdc++.h>
#define db double
using namespace std;
const db pi=acos(-1.0);
const db eps=1e-8;
db dis2(db x,db y,db i,db j)
{
	return (x-i)*(x-i)+(y-j)*(y-j);
}
int t;
db rx,ry,r,x,y,ex,ey;
db a,b,arg1,arg2,arg3;
db res;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lf%lf%lf%lf%lf",&rx,&ry,&r,&x,&y);
		ex=rx;ey=ry-r;
		a=dis2(x,y,rx,ry);
		b=dis2(x,y,ex,ey);
		arg1=acos((a+r*r-b)/(2.0*sqrt(a)*r));
		arg2=acos(r/sqrt(a));
		arg3=arg1-arg2;
		if(arg3<=pi/2+eps)//切点在下半圆周 
		{
			if(x<rx)res=dis2(x,y,rx-r,ry);
			else res=dis2(x,y,rx+r,ry);
			printf("%.4lf\n",sqrt(res)+pi*r/2.0);
		}
		else printf("%.4lf\n",sqrt(a-r*r)+arg3*r);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小衣同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值