51NOD 1265 四点共面 【简单几何分析】

1265 四点共面

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题

给出三维空间上的四个点(点与点的位置均不相同),判断这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,四个点共面的充要条件是满足存在实数x,y,z使得 ax+by+cz=0 成立,这里我们可以根据行列式的性质,参考克拉姆法则,然后特判下是否为0即可,另一种思路就是,看三个向量对应的两个法向量是否平行,如果平行的话就成立否则不成立,(这里直接套板子

行列式参考代码

#include<bits/stdc++.h>

using namespace std;

#define eps 1e-12

int main(){
    ios_base::sync_with_stdio(0);
    int T;cin>>T;
    while (T--) {
    double x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4;
    cin>>x1>>y1>>z1>>x2>>y2>>z2>>x3>>y3>>z3>>x4>>y4>>z4;
    double v1x,v2x,v3x,v1y,v2y,v3y,v1z,v2z,v3z;
    v1x = x2 - x1; v1y = y2 - y1; v1z = z2 - z1;
    v2x = x3 - x1; v2y = y3 - y1; v2z = z3 - z1;
    v3x = x4 - x1; v3y = y4 - y1; v3z = z4 - z1;
    if(fabs((v1x*v2y*v3z + v1y*v2z*v3x + v1z*v2x*v3y - v1z*v2y*v3x - v2x*v1y*v3z - v1x*v3y*v2z) - 0) < eps) {
        cout<<"Yes"<<endl;
    } else {
        cout<<"No"<<endl;
    }}
    return 0;
}

法向量参考代码

#include<bits/stdc++.h>

using namespace std;

#define eps 1e-12

struct Point3 {
    double x,y,z;
    Point3(double x = 0, double y = 0, double z = 0):x(x),y(y),z(z){};
};
typedef Point3 Vector3;

Vector3 operator - (Point3 A, Point3 B) {
    return Vector3(A.x - B.x,A.y - B.y,A.z - B.z);
}

//点乘积
double Dot (Vector3 A,Vector3 B) {
    return A.x*B.x + A.y*B.y + A.z*B.z;
}

double Length(Vector3 A) {
    return sqrt(Dot(A,A));
}

//叉积
Vector3 Cross (Vector3 A,Vector3 B) {
    return Vector3(A.y*B.z - A.z*B.y, A.z*B.x - A.x*B.z, A.x*B.y - A.y*B.x);
}

double Area2(Vector3 A, Vector3 B) {
    return Length(Cross(A,B));
}

double dcmp(double x) {
    if(fabs(x) < eps) return 0;
    return x < 0 ? -1 : 1;
}

int main(){
    ios_base::sync_with_stdio(0);
    int T;cin>>T;
    while (T--) {
        Point3 p1,p2,p3,p4;
        cin>>p1.x>>p1.y>>p1.z>>p2.x>>p2.y>>p2.z>>p3.x>>p3.y>>p3.z>>p4.x>>p4.y>>p4.z;
        Vector3 tv1 = p1 - p2, tv2 = p1 - p3,tv3 = p1 - p4;
        Vector3 v1 = Cross(tv1,tv2),v2 = Cross(tv1,tv3);
        double ans = Area2(v1,v2);
        dcmp(ans) ? puts("No"):puts("Yes");
    }
    return 0;
}
  • 如有错误或遗漏,请私聊下UP,thx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值