三维空间中有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); }