问题 A: 梦想成为天文学家
题目描述
璟哥哥从小想成为天文学家,这是个伟大的梦想。
为了实现这个梦想,璟哥哥天天都要观测星星。璟哥哥家里很有钱,所以买了一个精密的天文望远镜来专门观测各种星星。
这个天文望远镜可以算出被观测星星的准确坐标(x,y,z),星星所处的位置当然是三维的。
但是这个天文望远镜非常耗电,所以一天只能观测4颗星星。
璟哥哥查阅资料发现,如果4颗星星处于一个平面上,他们就是同一个星系里的恒星。
但是璟哥哥很笨,你能告诉他每天观测的4颗星星是否处在同一个星系吗?
输入
测试数据的第一行输入为T(0 <= T <= 100),表示测试样例的数量。
对于每一个测试样例,都有4行。
每一行包含3个整数 x,y,z,表示一个星星的坐标(-1000 <= x,y,z <= 1000)。
输出
输出的格式为"Day #x: “(不包含引号),x为相应的样例编号。
如果4颗星星处于同一个星系,输出"Yes”,否则输出"No"。
样例输入
1
1 2 0
2 3 0
4 0 0
0 0 0
样例输出
Day #1: Yes
思想:三个点可以确定一个平面,先根据三个点可以弄出两个向量,两个向量叉乘可以求出法向量,再用这个法向量和(第四个点和其他任意一点组成的向量)去判断是否垂直 垂直了就四点共面
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8;
int sgn(double x){
if(fabs(x)<eps) return 0;
else if(x<0) return -1;
return 1;
}
struct Point{
double x,y,z;
Point(){}
Point(double _x,double _y,double _z){
x=_x;
y=_y;
z=_z;
}
void input(){
scanf("%lf%lf%lf",&x,&y,&z);
}
double operator * (const Point b) const{
return x*b.x+y*b.y+z*b.z;
}
Point operator ^ (const Point b) const{
return Point(y*b.z-b.y*z,b.x*z-b.z*x,x*b.y-y*b.x);
}
Point operator + (const Point b) const{
return Point(x+b.x,y+b.y,z+b.z);
}
Point operator - (const Point b) const{
return Point(x-b.x,y-b.y,z-b.z);
}
};
int main(){
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++){
Point a,b,c,d;
a.input();
b.input();
c.input();
d.input();
Point ab,ac,ad,o;
ab=b-a;
ac=c-a;
ad=d-a; //第四个点和其他任意一点组成的向量
o=ab^ac; //法向量
if(sgn(o*ad)==0)
printf("Day #%d: Yes\n",i);
else
printf("Day #%d: No\n",i);
}
}