1. 程式人生 > >codeM D神奇的盤子(對圓上每一點暴力的新姿勢)

codeM D神奇的盤子(對圓上每一點暴力的新姿勢)

IT BE ret SQ boa urn return 2.0 printf

鏈接: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;
} 

  

codeM D神奇的盤子(對圓上每一點暴力的新姿勢)