寻找三角形

三维空间中有N个点,每个点可能是三种颜色的其中之一,三种颜色分别是红绿蓝,分别用'R', 'G', 'B'表示。
现在要找出三个点,并组成一个三角形,使得这个三角形的面积最大。
但是三角形必须满足:三个点的颜色要么全部相同,要么全部不同。
输入描述:
首先输入一个正整数N三维坐标系内的点的个数.(N <= 50) 

接下来N行,每一行输入 c x y z,c为'R', 'G', 'B' 的其中一个。x,y,z是该点的坐标。(坐标均是0到999之间的整数)


输出描述:
输出一个数表示最大的三角形面积,保留5位小数。

输入例子1:
5
R 0 0 0
R 0 4 0
R 0 0 3
G 92 14 7
G 12 16 8

输出例子1:
6.00000

思路:


 
 
向量叉积
我们来回顾一下三维向量叉积(向量积,如果用同济版高数的话)的几何意义:
2个向量X和Y的叉积A,方向与这两个叉积组成的平面垂直,
A的模的大小(A向量的长度),是由X、Y这两个向量组成的平行四边形的面积。
(或者说,是由这两个向量组成的三角形的面积的2倍 )。
真忘得一干二净的同学,请去参考你们的高数课本。
高数课本看不懂的,可以去买一本《算法艺术与信息学竞赛》,阅读其几何部分(讲得挺好、挺清楚的)。
所以说啊,写个叉积就好了。
(而且这个写法只需要在最后计算一次sqrt就行了,而不需要3次
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
class Node{
    private:
    	int x,y,z;
    public:
    Node(int _x=0,int _y=0,int _z=0):x(_x),y(_y),z(_z){}
    void get(){cin>>x>>y>>z;}
    Node get_across(const Node &b)const
        {
        return Node(y*b.z-z*b.y,z*b.x-x*b.z,x*b.y-y*b.x);
    }
    double get_length() const{
        return sqrt((ll)x*x+(ll)y*y+(ll)z*z);
    }
    Node operator-(const Node &b)const
        {
        return Node(x-b.x,y-b.y,z-b.z);
    }
    ~Node(){}
};
typedef vector<Node> vn;
vn R,B,G;
double Area=0.0;
void loop(vn &R,vn &G,vn &B){
    for(vn::iterator i=R.begin();i!=R.end();++i)
        for(vn::iterator j=G.begin();j!=G.end();++j)
            for(vn::iterator k=B.begin();k!=B.end();++k)
                {
				Node sa=*j-*i;
                Node sb=*k-*i;
                Area=max(Area,sa.get_across(sb).get_length()*0.5);
            }
}
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        char c;
        cin>>c;
        Node n;
        n.get();
        if(c=='R') R.push_back(n);
        if(c=='G') G.push_back(n);
        if(c=='B') B.push_back(n);
    }
    loop(R,R,R);
    loop(G,G,G);
    loop(B,B,B);
    loop(R,G,B);
    printf("%0.5f",Area);
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值