给出三维空间上的四个点(点与点的位置均不相同),判断这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; }