给出三维空间上的四个点(点与点的位置均不相同),判断这4个点是否在同一个平面内(4点共线也算共面)。如果共面,输出"Yes",否则输出"No"。
Input
第1行:一个数T,表示输入的测试数量(1 <= T <= 1000) 第2 - 4T + 1行:每行4行表示一组数据,每行3个数,x, y, z, 表示该点的位置坐标(-1000 <= x, y, z <= 1000)。
Output
输出共T行,如果共面输出"Yes",否则输出"No"。
Input示例
1 1 2 0 2 3 0 4 0 0 0 0 0
Output示例
Yes
编程之美.....
判断四点共面可以用向量的方法,首先,我们假设a,b,c,d四点共面,我们知道,三个向量可能共线,可能共面,也可能在同一个三维空间内,如果学过线性代数的话就会知道,三个向量如果线性相关,则至少存在一个向量能够被其余的两个向量线性表示,这就意味着这三个向量只能在一个平面内或者在一条直线上了,如此便证明了三个向量共面,我们设 ba,ca,da三个向量,如果这三个向量线性相关便能证明 a,b,c,d四点共面了,那么如果三个向量线性相关,那么必有不全为0的三个数 i,j,k使得 i*ba+j*ca+k*da=0,此齐次方程组有非零解,则其系数行列式的值一定等于0(根据克拉默法则),即的行列式为0,由此判断就可以了。
#include <iostream>
using namespace std;
struct pot
{
double x,y,z;
}a,b,c,d;
struct vec
{
double x,y,z;
}ba,ca,da;
double Judge(pot a, pot b, pot c, pot d)
{
ba.x=a.x-b.x; ba.y=a.y-b.y; ba.z=a.z-b.z;
ca.x=a.x-c.x; ca.y=a.y-c.y; ca.z=a.z-c.z;
da.x=a.x-d.x; da.y=a.y-d.y; da.z=a.z-d.z;
double num=ba.x*ca.y*da.z + ca.x*da.y*ba.z + da.x*ba.y*ca.z,
num1=da.x*ca.y*ba.z + da.y*ca.z*ba.x + ca.x*ba.y*da.z;
return num-num1;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>a.x>>a.y>>a.z>>b.x>>b.y>>b.z>>c.x>>c.y>>c.z>>d.x>>d.y>>d.z;
if(Judge(a,b,c,d))
{
cout<<"No"<<endl;
}
else
cout<<"Yes"<<endl;
}
return 0;
}