2021牛客暑期多校训练营2
F.Girlfriend
题意
给出 A ( x 0 , y 0 , z 0 ) , B ( x 1 , y 1 , z 1 ) , C ( x 2 , y 2 , z 2 ) , D ( x 3 , y 3 , z 3 ) , k 1 , k 2 A(x_{0},y_{0},z_{0}),B(x_{1},y_{1},z_{1}),C(x_{2},y_{2},z_{2}),D(x_{3},y_{3},z_{3}),k_{1},k_{2} A(x0,y0,z0),B(x1,y1,z1),C(x2,y2,z2),D(x3,y3,z3),k1,k2
要求计算限制条件下 P 1 , P 2 P_{1},P_{2} P1,P2两点的合法空间的相交部分体积
思路
A ( x 0 , y 0 , z 0 ) , B ( x 1 , y 1 , z 1 ) , P 1 ( x , y , z ) A(x_0,y_0,z_0),B(x_1,y_1,z_1),P_1(x,y,z) A(x0,y0,z0),B(x1,y1,z1),P1(x,y,z) 根据限制条件写出关系式: ( x − x 0 ) 2 + ( y − y 0 ) 2 + ( z − z 0 ) 2 ≥ k 1 2 ∗ [ ( x − x 1 ) 2 + ( y − y 1 ) 2 + ( z − z 1 ) 2 ] (x- x_0)^2+(y-y_0)^2+(z-z_0)^2\geq k_1^2*[(x-x_1)^2+(y-y1)^2+(z-z_1)^2] (x−x0)2+(y−y0)2+(z−z0)2≥k12∗[(x−x1)2+(y−y1)2+(z−z1)2]
化简得 ( k 1 2 − 1 ) ( x 2 + y 2 + z 2 ) − ( 2 k 1 2 x 1 − 2 x 0 ) x − ( 2 k 1 2 y 1 − 2 y 0 ) y − ( 2 k 1 2 z 1 − 2 z 0 ) z + k 1 2 ( x 1 2 + y 1 2 + z 1 2 ) − x 0 2 − y 0 2 − z 0 2 ≤ 0 (k_1^2−1)(x^2+y^2+z^2)−(2k_1^2x_1−2x_0)x−(2k_1^2y_1−2y_0)y−(2k_1^2z_1−2z_0)z+k_1^2(x_1^2+y_1^2+z_1^2)−x_0^2−y_0^2−z_0^2≤0 (k12−1)(x2+y2+z2)−(2k12x1−2x0)x−(2k12y1−2y0)y−(2k12z1−2z0)z+k12(x12+y12+z12)−x02−y02−z02≤0
再化简得 ( x 2 + y 2 + z 2 ) − 2 k 1 2 x 1 − 2 x 0 k 1 2 − 1 x − 2 k 1 2 y 1 − 2 y 0 k 1 2 − 1 y − 2 k 1 2 z 1 − 2 z 0 k 1 2 − 1 z + k 1 2 ( x 1 2 + y 1 2 + z 1 2 ) − x 0 2 − y 0 2 − z 0 2 k 1 2 − 1 ≤ 0 (x^2+y^2+z^2)−\frac{2k_1^2x_1−2x_0}{k_1^2−1}x−\frac{2k_1^2y_1−2y_0}{k_1^2−1}y−\frac{2k_1^2z_1−2z_0}{k_1^2−1}z+\frac{k_1^2(x_1^2+y_1^2+z_1^2)−x_0^2−y_0^2−z_0^2}{k_1^2−1}≤0 (x2+y2+z2)−k12−12k12x1−2x0x−k12−12k12y1−2y0y−k12−12k12z1−2z0z+k12−1k12(x12+y12+z12)−x02−y02−z02≤0
前置处理圆心 a = 2 k 1 2 x 1 − 2 x 0 k 1 2 − 1 a =\frac{2k_1^2x_1−2x_0}{k_1^2−1} a=k12−12k12x1−2x0 b = 2 k 1 2 y 1 − 2 y 0 k 1 2 − 1 b = \frac{2k_1^2y_1−2y_0}{k_1^2−1} b=k12−12k12y1−2y0 c = 2 k 1 2 z 1 − 2 z 0 k 1 2 − 1 c = \frac{2k_1^2z_1−2z_0}{k_1^2−1} c=k12−12k12z1−2z0 d = k 1 2 ( x 1 2 + y 1 2 + z 1 2 ) − x 0 2 − y 0 2 − z 0 2 k 1 2 − 1 d = \frac{k_1^2(x_1^2+y_1^2+z_1^2)−x_0^2−y_0^2−z_0^2}{k_1^2−1} d=k12−1k12(x12+y12+z12)−x02−y02−z02 r = a 2 + b 2 + c 2 − d = ( 2 k 1 2 x 1 − 2 x 0 k 1 2 − 1 ) 2 + ( 2 k 1 2 y 1 − 2 y 0 k 1 2 − 1 ) 2 + ( 2 k 1 2 z 1 − 2 z 0 k 1 2 − 1 ) 2 − k 1 2 ( x 1 2 + y 1 2 + z 1 2 ) − x 0 2 − y 0 2 − z 0 2 k 1 2 − 1 r = \sqrt{a^2+b^2+c^2-d } =\sqrt{(\frac{2k_1^2x_1−2x_0}{k_1^2−1})^2+(\frac{2k_1^2y_1−2y_0}{k_1^2−1})^2+(\frac{2k_1^2z_1−2z_0}{k_1^2−1})^2-\frac{k_1^2(x_1^2+y_1^2+z_1^2)−x_0^2−y_0^2−z_0^2}{k_1^2−1}} r=a2+b2+c2−d=(k12−12k12x1−2x0)2+(k12−12k12y1−2y0)2+(k12−12k12z1−2z0)2−k12−1k12(x12+y12+z12)−x02−y02−z02
球的一般方程: x 2 + y 2 + z 2 + 2 a x + 2 b y + 2 c z + d = 0 x^2+y^2+z^2+2ax+2by+2cz+d=0 x2+y2+z2+2ax+2by+2cz+d=0
化作标准方程: ( x + a ) 2 + ( y + b ) 2 + ( z + c ) 2 = a 2 + b 2 + c 2 − d (x+a)^2+(y+b)^2+(z+c)^2=a^2+b^2+c^2-d (x+a)2+(y+b)2+(z+c)2=a2+b2+c2−d
球心: O ( − a , − b , − c ) O(-a,-b,-c) O(−a,−b,−c) 半径: r = a 2 + b 2 + c 2 − d r = \sqrt{a^2+b^2+c^2-d } r=a2+b2+c2−d
两圆心之间的距离: d i s = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 + ( z 1 − z 2 ) 2 dis = \sqrt{(x_1-x_2)^2+(y_1-y_2)^2+(z_1-z_2)^2} dis=(x1−x2)2+(y1−y2)2+(z1−z2)2
如果 d i s ≥ R 1 + R 2 dis \geq R_1 + R_2 dis≥R1+R2 体积为 0 0 0
如果 d i s + R 1 ≤ R 2 dis + R_1 \leq R_2 dis+R1≤R2 体积为 R 1 R_1 R1的体积
如果 d i s + R 2 ≤ R 1 dis + R_2 \leq R_1 dis+R2≤R1 体积为 R 2 R_2 R2 的体积
如果 R 1 + R 2 ≥ d i s R_1+R_2 \geq dis R1+R2≥dis 求出相交的体积
必要前提: c o s α = r 2 + d 2 − R 2 2 r d cos\alpha=\frac{r^2+d^2-R^2}{2rd} cosα=2rdr2+d2−R2
h 2 = r − r ∗ c o s α h_2=r-r*cos\alpha h2=r−r∗cosα
令 h 2 h_2 h2中的某一点到E点的距离为 x x x 所在圆面的半径为 r 2 − ( r ∗ c o s α + x ) \sqrt{r^2-(r*cos\alpha+x)} r2−(r∗cosα+x) 圆面的面积为 π [ r 2 − ( r ∗ c o s α + x ) 2 ] \pi[r^2-(r*cos\alpha+x)^2] π[r2−(r∗cosα+x)2]
用积分求出右边小圆截出的体积
V 1 = ∫ 0 h 2 π ( r 2 − ( r ∗ c o s α + x ) 2 ) d x V_1=\int_{0}^{h_2}{\pi(r^2-(r*cos\alpha+x)^2)}dx V1=∫0h2π(r2−(r∗cosα+x)2)dx
= ∫ 0 h 2 π ( r 2 − ( r 2 c o s 2 α + x 2 + 2 r x c o s α ) ) d x =\int_{0}^{h_2}{\pi(r^2-(r^2cos^2\alpha+x^2+2rxcos\alpha))}dx =∫0h2π(r2−(r2cos2α+x2+2rxcosα))dx
= ∫ 0 h 2 π ( r 2 s i n 2 α − x 2 − 2 r x c o s α ) d x =\int_{0}^{h_2}{\pi(r^2sin^2\alpha -x^2-2rxcos\alpha)}dx =∫0h2π(r2sin2α−x2−2rxcosα)dx
= π ( − 1 3 h 2 3 − r h 2 2 c o s α + r 2 h 2 s i n 2 α ) =\pi(-\frac{1}{3}h_2^3-rh_2^2cos\alpha+r^2h_2sin^2\alpha) =π(−31h23−rh22cosα+r2h2sin2α)
= π ( r h 2 ( r s i n 2 α − h 2 c o s α ) − 1 3 h 2 3 ) =\pi(rh_2(rsin^2\alpha-h_2cos\alpha)-\frac{1}{3}h_2^3) =π(rh2(rsin2α−h2cosα)−31h23)
= π ( r h 2 ( r ( 1 − c o s 2 α ) − h 2 c o s α ) − 1 3 h 2 3 ) =\pi(rh_2(r(1-cos^2\alpha)-h_2cos\alpha)-\frac{1}{3}h_2^3) =π(rh2(r(1−cos2α)−h2cosα)−31h23)
= π ( r h 2 ( r − r c o s 2 α − h 2 c o s α ) − 1 3 h 2 3 ) =\pi(rh_2(r-rcos^2\alpha-h_2cos\alpha)-\frac{1}{3}h_2^3) =π(rh2(r−rcos2α−h2cosα)−31h23)
= π ( r h 2 ( r − c o s α ( r c o s α + h 2 ) ) − 1 3 h 2 3 ) =\pi(rh_2(r-cos\alpha(rcos\alpha+h_2))-\frac{1}{3}h_2^3) =π(rh2(r−cosα(rcosα+h2))−31h23)
= π ( r h 2 ( r − c o s α ( r c o s α + h 2 ) ) − 1 3 h 2 3 ) =\pi(rh_2(r-cos\alpha(rcos\alpha+h_2))-\frac{1}{3}h_2^3) =π(rh2(r−cosα(rcosα+h2))−31h23)
= π ( r h 2 ( r − r c o s α ) − 1 3 h 2 3 ) =\pi(rh_2(r-rcos\alpha)-\frac{1}{3}h_2^3) =π(rh2(r−rcosα)−31h23)
= π ( r h 2 2 − 1 3 h 2 3 ) =\pi(rh_2^2-\frac{1}{3}h_2^3) =π(rh22−31h23)
= π h 2 2 ( r − 1 3 h 2 ) =\pi h_2^2(r-\frac{1}{3}h_2) =πh22(r−31h2)
同理可以求出大圆体积
V 2 = π h 1 2 ( R − 1 3 h 1 ) V_2=\pi h_1^2(R - \frac{1}{3}h_1) V2=πh12(R−31h1)
V = V 1 + V 2 = π h 2 2 ( r − 1 3 h 2 ) + π h 1 2 ( R − 1 3 h 1 ) V = V1+ V2 =\pi h_2^2(r-\frac{1}{3}h_2)+\pi h_1^2(R - \frac{1}{3}h_1) V=V1+V2=πh22(r−31h2)+πh12(R−31h1)
代码
#include<bits/stdc++.h>
using namespace std;
int t;
double x[5], y[5], z[5];
double k1, k2;
const double PI = acos(-1);
void solve(double x1, double y1, double z1, double r1, double x2, double y2, double z2, double r2) {
double dis = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
double ans = 0;
if (dis >= r1 + r2) {
ans = 0;
}
else if (dis + r1 <= r2) {
ans = (4.00 / 3.00) * PI * r1 * r1 * r1;
}
else if (dis + r2 <= r1) {
ans = (4.00 / 3.00) * PI * r2 * r2 * r2;
}
else {
double c1 = (r1 * r1 + dis * dis - r2 * r2) / (2.00 * dis * r1);
double h1 = r1 * (1.00 - c1);
ans += (1.00 / 3.00) * PI * (3.00 * r1 - h1) * h1 * h1;
double c2 = (r2 * r2 + dis * dis - r1 * r1) / (2.00 * dis * r2);
double h2 = r2 * (1.00 - c2);
ans += (1.00 / 3.00) * PI * (3.00 * r2 - h2) * h2 * h2;
}
printf("%.3lf\n", ans);
}
int main() {
cin >> t;
while (t--) {
for (int i = 0; i < 4; i++) {
cin >> x[i] >> y[i] >> z[i];
}
cin >> k1 >> k2;
double kk1 = k1 * k1 - 1;
double c1x, c1y, c1z, c1r, d;
c1x = (k1 * k1 * x[1] - x[0]) / kk1;
c1y = (k1 * k1 * y[1] - y[0]) / kk1;
c1z = (k1 * k1 * z[1] - z[0]) / kk1;
d = k1 * k1 * ((x[1] * x[1]) + (y[1] * y[1]) + (z[1] * z[1])) - (x[0] * x[0] + y[0] * y[0] + z[0] * z[0]);
d /= kk1;
c1r = sqrt(c1x * c1x + c1y * c1y + c1z * c1z - d);
double kk2 = k2 * k2 - 1;
double c2x, c2y, c2z, c2r, d2;
c2x = (k2 * k2 * x[3] - x[2]) / kk2;
c2y = (k2 * k2 * y[3] - y[2]) / kk2;
c2z = (k2 * k2 * z[3] - z[2]) / kk2;
d2 = k2 * k2 * ((x[3] * x[3]) + (y[3] * y[3]) + (z[3] * z[3])) - (x[2] * x[2] + y[2] * y[2] + z[2] * z[2]);
d2 /= kk2;
c2r = sqrt(c2x * c2x + c2y * c2y + c2z * c2z - d2);
solve(c1x, c1y, c1z, c1r, c2x, c2y, c2z, c2r);
}
return 0;
}
参考:
大佬题解:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=48338562
大佬推导公式:https://blog.csdn.net/ouyangcheese/article/details/115421270