【题目描述】
现在用纸制作一个 A ∗ B ∗ C A*B*C A∗B∗C的纸盒,将这个纸盒的六个面展开铺开在一个平面直角坐标系中的图形如下:
给出 这个坐标系中的两点坐标 ( x 1 , y 1 ) (x_1,y_1) (x1,y1), ( x 2 , y 2 ) (x_2,y_2) (x2,y2),保证这两点一定在纸盒的面上,请你求出在折成纸盒之后这两点在空间中的直线距离(欧几里得距离)。
【输入格式】
第一行三个整数 A , B , C A,B,C A,B,C。
接下来两行每行两个小数,分别为给出的两点坐标值 x i , y i x_i,y_i xi,yi。
【输出格式】
输出一行一个小数,表示答案,答案四舍五入至5位小数。
【数据范围】
不重要所以不写了
给一个数据吧:
99
input
7 531 693
856.65 885.42
1031.05 650.58
output
292.515274
显然,这是一道大家都爱的数学题,那么对代码能力的考验自然不大,主要就是在思维上啦。(像博主这样不太聪明的蒟蒻就不擅长)。
聪明一点的同学可能知道三维两点的距离公式,那么不知道也没关系,因为以后你就知道了:
给定两个点 A ( x 1 , y 1 , z 1 ) A(x_1,y_1,z_1) A(x1,y1,z1), B ( x 2 , y 2 , z 2 ) B(x_2,y_2,z_2) B(x2,y2,z2),则这两个点的距离为:
D = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 + ( z 1 − z 2 ) 2 D=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2+(z_1-z_2)^2} D=(x1−x2)2+(y1−y2)2+(z1−z2)2
(特地放大强调一下)
公式其实是很好推的,自己在纸上画画就懂了,实在不懂的话,看下图吧(无奈)
(有些简陋,凑合看看吧)
点 A A A点 B B B分别在面 S 1 S1 S1 S 2 S2 S2上,两个面夹角为 90 ° 90° 90°, B C BC BC、 A D AD AD分别与底面平行。求 A A A, B B B距离即线段 A B AB AB的长度,首先求出 B C BC BC、 C D CD CD、 A D AD AD的长度, ① A C = A D 2 + C D 2 ①AC=\sqrt{AD^2+CD^2} ①AC=AD2+CD2。将AC,BC放于同一平面,勾股定理可得 ② A B = A C 2 + B C 2 ②AB=\sqrt{AC^2+BC^2} ②AB=AC2+BC2。
将①式代入②式即可得公式。
既然知道了如何求三维空间中两点的距离,那么本题就可以转化成求平面上两点在三维空间中的坐标啦!
这一步说起来简单,其实细节也挺多的,一下为具体代码和代码对应建系的图:
#include<bits/stdc++.h>
using namespace std;
double a,b,c,x,y,xx,yy,ans;
struct node{
double x,y,z;
}pos[3];
void conversion(int id,double xxx,double yyy){
if(xxx<=c&&yyy>=b+c&&yyy<=2*b+c) pos[id].x=0, pos[id].y=c-xxx, pos[id].z=yyy-c-b;
if(xxx>=c&&xxx<=a+c&&yyy<=(c+b)*2&&yyy>=2*b+c) pos[id].x=xxx-c, pos[id].y=yyy-b*2-c, pos[id].z=b;
if(xxx>c&&xxx<a+c&&yyy<2*b+c&&yyy>b+c) pos[id].x=xxx-c, pos[id].y=0, pos[id].z=yyy-c-b;
if(xxx>=c&&xxx<=a+c&&yyy<=c+b&&yyy>=b) pos[id].x=xxx-c, pos[id].y=b+c-yyy, pos[id].z=0;
if(yyy<b) pos[id].x=xxx-c, pos[id].y=c, pos[id].z=b-yyy;
if(xxx>=a+c&&yyy<=2*b+c&&yyy>=b+c) pos[id].x=a, pos[id].y=xxx-a-c, pos[id].z=yyy-b-c;
}
double gougu(double x,double y,double z){
return sqrt(x*x+y*y+z*z);
}
int main(){
cin>>a>>b>>c>>x>>y>>xx>>yy;
conversion(1,x,y);
conversion(2,xx,yy);
printf("%lf",gg(pos[1].x-pos[2].x,pos[1].y-pos[2].y,pos[1].z-pos[2].z));
return 0;
}
其中 c o n v e r s i o n conversion conversion函数是我认为最重要的(改了好久)注意思考在每一个面上的点的坐标与原坐标的关系,必要的时候也可以手凹一个立体模型帮助理解,可以避免掉许多错误。
在理解的基础上怎样建系都可以啦!