http://acm.timus.ru/problem.aspx?space=1&num=1285
题意
给2个8维空间的点,再给个8维空间的“球”,问不与球相交的最短距离(保证点在“球”外)。
题解
作过这3个点的切面,化归为平面上的问题。需要注意的有:
如果圆与三角形底边无交点,则直接输出长度即可
如果三角形是钝角三角形,则依照题目保证直接输出长度即可
否则只可能是两条切线+一段圆弧
code
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
typedef long long LL;
const int maxn = 10;
int pa[maxn], pb[maxn], pc[maxn], R;
double dist(int* a, int *b) {
LL res = 0;
for (int i = 0; i < 8; ++ i)
res += (LL)(b[i]-a[i])*(b[i]-a[i]);
return sqrt(res);
}
void solve() {
for (int i = 0; i < 8; ++ i) scanf("%d", &pa[i]);
for (int i = 0; i < 8; ++ i) scanf("%d", &pb[i]);
for (int i = 0; i < 8; ++ i) scanf("%d", &pc[i]);
scanf("%d", &R);
double a = dist(pb, pc), b = dist(pa, pc), c = dist(pa, pb);
double p = (a+b+c) / 2.0;
double S = sqrt(p*(p-a)*(p-b)*(p-c));
double hc = 2.0*S / c;
if (R < hc) { printf("%.2lf\n", c); return; }
if (std::max(sqrt(a*a - hc*hc), sqrt(b*b - hc*hc)) > c) { printf("%.2lf\n", c); return; }
printf("%.2lf\n", sqrt(a*a-R*R) + sqrt(b*b-R*R) + R*(acos((a*a+b*b-c*c)/(2*a*b)) - (acos(R/a) + acos(R/b))));
}
int main() {
// freopen("C.in", "r", stdin);
solve();
// for(;;);
return 0;
}