2018-2019 ACM-ICPC, Asia East Continent Finals F. Interstellar … Fantasy(几何)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37025443/article/details/86349463

F. Interstellar … Fantasy

time limit per test

1.0 s

memory limit per test

256 MB

input

standard input

output

standard output

Unfortunately, the boy finally got bankrupt. Looking at his receding figure, Rikka understood more about the world — but she is still herself. Though, she still sat on the tower and spent time with the low gravity, feeling lost.

She looked at the deep dark sky, where the blue round Earth is shining overhead. Rikka thought about her families, her friends, and her homeland. Is she in her dream or a "real" world? The girl of chunibyo felt afraid for the first time since the journey began.

She saw a bright star traveling fast around the earth — maybe a geostationary space station. How could she get there? Daydream started again.

In other words, Rikka wonders the minimum distance she needs to travel from her position ss to the position of the star tt , while a sphere — the earth staying there as an obstacle. They are in a 3-dimensional Euclidean space. ss and tt may be at the same position.

Input

The first line contains an integer T (1≤T≤1000)T (1≤T≤1000) , the number of test cases. Then TT test cases follow.

Each test case contains two lines.

The first line contains four integers ox,oy,oz,rox,oy,oz,r , the positions in each dimension of the center of the sphere oo and its radius.

The second line contains six integers sx,sy,sz,tx,ty,tzsx,sy,sz,tx,ty,tz , the positions in each dimension of the starting point ss and the terminal point tt , respectively. Notice that ss and tt may be at the same position.

It is guaranteed that neither ss nor tt is strictly inside the obstacle, and each value of a position or a radius in the input belongs to [1,1000][1,1000] .

Output

Output one number, the minimum distance from ss to tt without entering the sphere obstacle. Your answer is considered correct if the absolute or relative error doesn't exceed 10−610−6 .

Example

Input

Copy

2
2 1 1 1
1 1 1 3 1 1
2 1 1 1
1 2 2 3 1 1

Output

Copy

3.14159265
2.64517298

题意:

给你两个点s,t和一个球o,问你从一个点到另一个点最短的距离是多少。因为球是实心的,所以经过球的时候你只能从球的表面走。

题目保证两个点一定不在球的内部

解析:

这道题比赛的时候想出思路了....但没有加特判.....

思路就是如果要经过球的话,那么肯定是相切着走最快。先从两个点做切边切球,从一个点出发先沿着切边走到球上,然后沿着球走到另外一个点的切边上,再沿着切边走到另外一个点,这个就是最近的走法。

但是如果走到两个点不需要经过球的话,直接就是两个点的直线距离。情况就有两种

1.两个点都在圆心的同一侧   => ∠ost>=90 || ∠ots >=90

2.两个点所连直线不与球相交  => o到st直线的距离h>半径R

比赛的时候忘叫了第一个特判...哎。。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>

using namespace std;

const double pi=acos(-1);

typedef struct node
{
	double x,y,z;
}node;



inline double calR(double a2,double b2,double c2)
{
	
	double ans=acos((a2+b2-c2)/(2*sqrt(a2*b2)));
	return ans;
}

inline double calDIS2(node a,node b)
{
	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z);
}



int main()
{
	int t;
	scanf("%d",&t);
	while (t--)
	{
		node oo;
		double R;
		node s,t;
		scanf("%lf%lf%lf%lf",&oo.x,&oo.y,&oo.z,&R);
		scanf("%lf%lf%lf%lf%lf%lf",&s.x,&s.y,&s.z,&t.x,&t.y,&t.z);
		
		double dis2_os=calDIS2(oo,s);
		double dis2_ot=calDIS2(oo,t);
		double dis2_st=calDIS2(s,t);
		if(dis2_st==0)
		{
			printf("%.15lf\n",0.0);
			continue;
		}
		double dis_os=sqrt(dis2_os);
		double dis_ot=sqrt(dis2_ot);
		double dis_st=sqrt(dis2_st);

		if(calR(dis2_ot,dis2_st,dis2_os)>=pi/2||calR(dis2_os,dis2_st,dis2_ot)>=pi/2)
		{
			printf("%.15lf\n",dis_st);
			continue;
		}
		double R_sot=calR(dis2_ot,dis2_os,dis2_st);
		double h=dis_os*dis_ot*sin(R_sot)/dis_st;

		if(h>=R)
		{
			printf("%.15lf\n",dis_st);
			continue;
		}

		double r1=acos(R/dis_os);
		double r2=acos(R/dis_ot);
		double ans1=sqrt(dis2_os-R*R);
		double ans2=sqrt(dis2_ot-R*R);
		double ans3=R*(R_sot-r1-r2);
		printf("%.15lf\n",ans1+ans2+ans3);


	}
}

猜你喜欢

转载自blog.csdn.net/qq_37025443/article/details/86349463