codeM D神奇的盘子(对圆上每一点暴力的新姿势)

链接:https://www.nowcoder.com/acm/contest/151/D
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld

题目描述

有一个神奇的盘子,形状为圆形。盘子上面爬着一个大象(视作一个点)。由于现实的扭曲,当大象在盘子某个直径的一端的时候,可以瞬间传送至直径的另一端。现在大象想去盘子上另外一点,问他最少需要移动多少距离。传送不计距离。

输入描述:

第一行一个整数r(1 <= r <= 1000)代表盘子的半径。
接下来两行两个整点分别代表大象所在的位置和大象目标的位置坐标。保证两个点都在圆内(可能在边界上),圆心在点(0, 0)上。

输出描述:

输出一个实数,代表大象最短需要移动多少距离。和标程相对或绝对相差1e-6都算正确。
示例1

输入

复制
1
0 1
0 -1

输出

复制
0.000000000000
示例2

输入

复制
4
3 0
-3 0

输出

复制
2.000000000000

说明

示例3

输入

复制
100
-59 76
3 69

输出

复制
62.393909959226
#include<bits/stdc++.h>
using namespace std;
struct p{double x,y,r;}a,b;
double r,R,pi=acos(-1.0);
double dis(double a,double b){return a*a+b*b;}
bool eps(double x,double y){return fabs(x-y)<1e-6;};
double solve(p a,p b){
	double res=4*r*r;
	if(eps(a.r,r)||eps(b.r,r)) return dis(a.x-b.x,a.y-b.y);
	for(double t=0.0;t<=2*pi;t+=0.00001){
		p tmp={R*cos(t),R*sin(t),1.0};
		res=min(res,sqrt(dis(tmp.x-a.x,tmp.y-a.y))+sqrt(dis(tmp.y-b.y,tmp.x-b.x)));
	}
	return res*res;
} 
int main(){
	scanf("%lf%lf%lf%lf%lf",&r,&a.x,&a.y,&b.x,&b.y);
	a.r=dis(a.x,a.y);b.r=dis(b.x,b.y);R=r,r=r*r;
	double aa=dis(a.x-b.x,a.y-b.y);
	b.x*=-1;b.y*=-1;
	aa=min(aa,solve(a,b));
	printf("%.6lf\n",sqrt(aa));
	return 0;
} 

  

猜你喜欢

转载自www.cnblogs.com/vainglory/p/9218757.html