首页 > 试题广场 >

寻找三角形

[编程题]寻找三角形
  • 热度指数:6617 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
三维空间中有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

输出

6.00000
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int num = sc.nextInt();

        int[] px = new int[num];
        int[] py = new int[num];
        int[] pz = new int[num];
        char[] colourArr = new char[num];


        for (int i = 0; i < num; i++) {
            colourArr[i] = sc.next().charAt(0);
            px[i] = sc.nextInt();
            py[i] = sc.nextInt();
            pz[i] = sc.nextInt();
        }

        double maxArea = 0;

        for(int i = 0; i < num; i++){
            for(int j = 0; j < num; j++) {
                if(j == i){
                    continue;
                }

                for(int k = 0; k < num; k++){
                    if(k == i || k == j){
                        continue;
                    }
                    if(colourArr[k] == colourArr[i] && colourArr[k] == colourArr[j]){
                        //3个相同颜色的点
                        double area = getArea(px[i], py[i], pz[i], px[j], py[j], pz[j], px[k], py[k], pz[k]);
                        if(area > maxArea){
                            maxArea = area;
                        }
                    }
                    else if(colourArr[k] != colourArr[i] && colourArr[k] != colourArr[j] && colourArr[i] != colourArr[j]){
                        //3个不同颜色的点
                        double area = getArea(px[i], py[i], pz[i], px[j], py[j], pz[j], px[k], py[k], pz[k]);
                        if(area > maxArea){
                            maxArea = area;
                        }
                    }

                }
            }
        }


        System.out.println(String.format("%.5f", maxArea));
    }


    //海伦公式
    //(p=(a+b+c)/2)
    //S=sqrt[p(p-a)(p-b)(p-c)]


    public static double getArea(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3){
        double a = Math.sqrt( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) + (z1-z2) * (z1-z2) );
        double b = Math.sqrt( (x2-x3) * (x2-x3) + (y2-y3) * (y2-y3) + (z2-z3) * (z2-z3) );
        double c = Math.sqrt( (x1-x3) * (x1-x3) + (y1-y3) * (y1-y3) + (z1-z3) * (z1-z3) );

        double p = (a + b + c) / 2;

        double area = Math.sqrt( p * (p - a) * (p - b) * (p - c) );

        return area;
    }
}

看了一下大神的才知道伦琴算法。。。然后就好办了- -穷举就完事了。。。

发表于 2020-02-01 10:18:14 回复(0)
更多回答
问题1:遍历所有可能的3个点
 for(int i = 0; i < n; i++)
   for(int j = i + 1; j < n; j++)
     for(int k = j + 1; k < n; k++)
问题2:判断3个点是否能组成三角形
double a = dis(i, j);     //计算两点距离
double b = dis(i, k);
double c = dis(k, j);
if(a < (b + c) && b < (a + c) && c < (a + b))
{
  return true;
}
return false;
问题3:判断颜色是否相同或全不同
if(V[i].c == V[j].c && V[j].c == V[k].c)
{
   return true;
}
else if(V[i].c != V[j].c &&V[i].c != V[k].c&&V[k].c != V[j].c)
{
  return true;
}
return false;
问题4:计算三角形面积 (海伦公式 百度~)
doublea = L3(i, j);
doubleb = L3(i, k);
doublec = L3(k, j);
doublep = (a + b + c) / 2;
return sqrt(p * (p - a) * (p - b) * (p - c));

附上源代码
#include<bits/stdc++.h>  
using namespace std;

/*
3
R 0 0 0
R 0 4 0
B 0 0 3
*/

struct node{
	char c;
	int x, y, z;
};

double MAX = 0;
int n;
vector<node> V;

//计算两点之间的举例
double L3(int i, int j){
	return sqrt(double((V[i].x - V[j].x)*(V[i].x - V[j].x) + (V[i].y - V[j].y)*(V[i].y - V[j].y) + (V[i].z - V[j].z)*(V[i].z - V[j].z)));
}

//判断是否是三角形
bool isSan(int i, int j, int k){
	double a = L3(i, j);
	double b = L3(i, k);
	double c = L3(k, j);
	if (a < (b + c) && b < (a + c) && c < (a + b))
	{
		return true;
	}
	return false;
}

//判断颜色
bool isColour(int i, int j, int k){
	if (V[i].c == V[j].c && V[j].c == V[k].c)
	{
		return true;
	}
	else if (V[i].c != V[j].c &&V[i].c != V[k].c&&V[k].c != V[j].c)
	{
		return true;
	}
	return false;
}

//计算三角形面积
double CmputeArea(int i, int j, int k){
	double a = L3(i, j);
	double b = L3(i, k);
	double c = L3(k, j);
	double p = (a + b + c) / 2;
	return  sqrt(p * (p - a) * (p - b) * (p - c));
}

//遍历所有可能的三个点
void run(){
	for (int i = 0; i < n; i++)
	{
		for (int j = i + 1; j < n; j++)
		{
			for (int k = j + 1; k < n; k++)
			{
				if (isSan(i, j, k) && isColour(i, j, k))
				{
					double tArea = CmputeArea(i, j, k);
					if (tArea > MAX)
					{
						MAX = tArea;
					}
				}
			}
		}
	}
}

int main(){
	cin >> n;

	for (int i = 0; i < n; i++)
	{
		node t;
		cin >> t.c >> t.x >> t.y >> t.z;
		V.push_back(t);
	}
	run();

	printf("%.5lf", MAX);

}

编辑于 2017-04-27 23:14:08 回复(19)
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
	
	static class Point{
		char color;
		int x;
		int y;
		int z;
	}
	
	// 计算两点之间的距离
	public static double distance(Point A, Point B){
		return Math.sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y) + (A.z-B.z)*(A.z-B.z));
	} 
	
	// 判断三个点颜色是否满足条件
	public static boolean colorIsMathed(Point A, Point B, Point C) {
		if (A.color == B.color && B.color == C.color) { // 三个点的颜色相同
			return true;
		}else if (A.color!=B.color && A.color!=C.color && B.color!=C.color) { // 三个点的颜色都不相同
			return true;
		}else {
			return false;
		}
	}
	
	// 判断三个点是否能构成三角形
	public static boolean isSan(Point A, Point B, Point C) {
		double a = distance(A, B);
		double b = distance(A, C);
		double c = distance(B, C);
	    if (a<(b+c) && b<(a+c) && c<(a+b)
	    	&& a>Math.abs(b-c) && b>Math.abs(a-c) && c>Math.abs(a-b)){
	        return true;
	    }
	    return false;
	}
	
	// 计算三角形面积
	public static double getArea(Point A, Point B, Point C) {
		double a = distance(A, B);
		double b = distance(A, C);
		double c = distance(B, C);
		double p = (a + b + c) / 2;
		return  Math.sqrt(p * (p - a) * (p - b) * (p - c));
	}
		
	public static void main(String[] args) {
		List<Point> list = new ArrayList<>();		
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		sc.nextLine();		
		// 将输入的点添加到 List 中
		for(int i = 0; i < n; i++){
			Point p = new Point();
			String[] arr = sc.nextLine().split(" ");
			p.color = arr[0].charAt(0);
			p.x = Integer.parseInt(arr[1]);
			p.y = Integer.parseInt(arr[2]);
			p.z = Integer.parseInt(arr[3]);
			list.add(p);			
		}
		
		double maxArea = 0;
		double area = 0;
		// 遍历所有可能的三个点
		for(int i = 0; i < n; i++){
			for (int j = i + 1; j < n; j++) {
				for (int k = j + 1; k < n; k++){
					Point A = list.get(i);
					Point B = list.get(j);
					Point C = list.get(k);
					
					if (isSan(A,B,C) && colorIsMathed(A,B,C)) {
						area = getArea(A, B, C);
					}
					if (area > maxArea) {
						maxArea = area;
					}
				}
			}
		}
		
		System.out.format("%.5f", maxArea);
		
	}

}
发表于 2017-05-03 23:22:15 回复(5)
你们的高数老师表示对你们非常失望。
怎么全都只记得中学学过的海伦公式啊?
大学里,我们学过一种更强大的工具啊:
向量叉积

我们来回顾一下三维向量叉积(向量积,如果用同济版高数的话)的几何意义:
2个向量X和Y的叉积A,方向与这两个叉积组成的平面垂直,
A的模的大小(A向量的长度),是由X、Y这两个向量组成的平行四边形的面积。
(或者说,是由这两个向量组成的三角形的面积的2倍 )。
真忘得一干二净的同学,请去参考你们的高数课本。
高数课本看不懂的,可以去买一本《算法艺术与信息学竞赛》,阅读其几何部分(讲得挺好、挺清楚的)。

所以说啊,写个叉积就好了。
(而且这个写法只需要在最后计算一次sqrt就行了,而不需要3次
如果出题人为了避免任何浮点数运算,让你输出面积的平方的2倍,嘿嘿嘿)
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;

struct Point{
	int x,y,z;
	explicit Point(int _x=0,int _y=0,int _z=0):x(_x),y(_y),z(_z){}
	void get(){
		scanf("%d%d%d",&x,&y,&z);
	}
	Point cross_product(const Point &b)const{
		return Point(y*b.z-z*b.y,
					z*b.x-x*b.z,
					x*b.y-y*b.x);
	}
	Point operator-(const Point &b)const{
		return Point(x-b.x,
					y-b.y,
					z-b.z);
	}
	double get_length(){
		return sqrt((ll)x*x+(ll)y*y+(ll)z*z);
	}
};

typedef vector<Point> vp;
typedef Point Vec;

double ans=0.0;

void loop(vp& a,vp& b,vp& c){
	for(vp::iterator i=a.begin();i!=a.end();++i){
		for(vp::iterator j=b.begin();j!=b.end();++j){
			for(vp::iterator k=c.begin();k!=c.end();++k){
				Vec sa=*j-*i;
				Vec sb=*k-*i;
				ans=max(ans,sa.cross_product(sb).get_length()*0.5);
			}
		}
	}
}

vector<Point> r,g,b;

int main(){
	int n;
	char tmp[3];
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%s",tmp);
		Point p;p.get();
		if(tmp[0]=='R')r.push_back(p);
		if(tmp[0]=='G')g.push_back(p);
		if(tmp[0]=='B')b.push_back(p);
	}
	loop(r,r,r);
	loop(g,g,g);
	loop(b,b,b);
	loop(r,g,b);
	printf("%.5f\n",ans);
	return 0;
} 


编辑于 2017-05-22 12:10:12 回复(11)
import math


class Point:
    def __init__(self, c, x, y, z):
        self.c = c
        self.x = x
        self.y = y
        self.z = z


def valid(l1, l2, l3):
    token = [l1, l2, l3]
    token.sort()
    return token[0] + token[1] > token[2]


def cal_l(p1, p2):
    l = pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2) + pow(p1.z - p2.z, 2)
    return math.sqrt(l)


def cal_s(c1, c2, c3):
    ans = 0
    l1 = cal_l(c1, c2)
    l2 = cal_l(c2, c3)
    l3 = cal_l(c1, c3)
    if valid(l1, l2, l3):
        p = (l1 + l2 + l3) / 2
        token = math.sqrt(p * (p - l1) * (p - l2) * (p - l3))  # 海伦公式
        ans = max(token, ans)
    return ans


N = int(input())
nums = []
for i in range(N):
    c, x, y, z = input().split(' ')
    nums.append(Point(c, int(x), int(y), int(z)))
ans = 0
for i in range(N-2):
    for j in range(i+1, N-1):
        for k in range(j+1, N):
            if nums[i].c == nums[j].c == nums[k].c or len(set([nums[i].c, nums[j].c, nums[k].c])) == 3:
                ans = max(ans, cal_s(nums[i], nums[j], nums[k]))
print('{:.5f}'.format(ans))

发表于 2017-09-07 10:56:59 回复(1)
#include <iostream>
#include <string>
#include <cmath>
#include <cstdio>

using namespace std;

struct Points { //定义结构体Points
    char c;
    int x, y, z;
};

double CountTriangleArea(Points A, Points B, Points C) { //根据三个点计算三角形面积
    double a = sqrt(pow(A.x - B.x, 2) + pow(A.y - B.y, 2) + pow(A.z - B.z, 2));
    double b = sqrt(pow(A.x - C.x, 2) + pow(A.y - C.y, 2) + pow(A.z - C.z, 2));
    double c = sqrt(pow(C.x - B.x, 2) + pow(C.y - B.y, 2) + pow(C.z - B.z, 2)); //计算三边长度a, b, c
    if (a + b <= c || a + c <= b || b + c <= a) //排除掉不符合的情形
        return -1;
    double p = (a + b + c) / 2;
    return sqrt(p * (p - a) * (p - b) * (p - c));
}

int main() {
    int N;
    Points p[N];
    double MaxArea = 0;
    for (int i = 0; i < N; cin >> p[i++].c >> p[i - 1].x >> p[i - 1].y >> p[i - 1].z);
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < N; ++j)
            if (i != j)
                for (int k = 0; k < N; ++k)
                    if (k != i && k != j && ((p[i].c != p[j].c && p[i].c != p[k].c
                                              && p[j].c != p[k].c) || (p[i].c == p[j].c && p[i].c == p[k].c)))
                        if (CountTriangleArea(p[i], p[j], p[k]) > MaxArea)
                            MaxArea = CountTriangleArea(p[i], p[j], p[k]);
    printf("%.5f", MaxArea);
}
编辑于 2017-05-02 11:52:55 回复(2)
#include<iostream>
#include<algorithm>
using namespace std;

struct node     //定义结构体:颜色col,和三维坐标,x,y,z
   {
      char col;
      int x,y,z;   
   };

double Max=0;
vector<node> V;  //用容器vector存取每个node的四个值

double  Dis(int i,int j)   //计算两点之间距离
   {
     double dis;
     dis=sqrt(double((V[i].x-V[j].x)*(V[i].x-V[j].x)+(V[i].y-V[j].y)*(V[i].y-V[j].y)+(V[i].z-V[j].z)*(V[i].z-V[j].z)));
     return dis;
   }

bool IsSan(int i,int j,int k)  //判断是否满足三角形的条件 {
       int a=Dis(i,j);
       int b=Dis(i,k);
       int c=Dis(j,k);
       if((a+b)>c&&(a+c)>b&&(b+c)>a)
           return true;
       else
           return false;
   }

bool Color(int i,int j,int k)  // 判断颜色是否一样或者是否全部不一样 {
      if((V[i].col==V[j].col)&&(V[j].col==V[k].col))
          return true;
      else if((V[i].col!=V[j].col)&&(V[j].col!=V[k].col)&&(V[i].col!=V[k].col))
          return true;
      return false;
   }

double  Area(int i,int j,int k)    //计算三角形的面积
    {
        double a=Dis(i,j);
        double b=Dis(i,k);
        double c=Dis(j,k);
        double p=(a+b+c)/2;
        double area=sqrt(p*(p-a)*(p-b)*(p-c));
        return area;
    }

int main()
    {
       int n;
       double area;
       cin>>n;
       node t;
       for(int i=0;i<n;i++)
         {
           cin>>t.col>>t.x>>t.y>>t.z;
           V.push_back(t);
         }
       for(int i=0;i<n;i++)
         {
           for(int j=i+1;j<n;j++)
              { for(int k=j+1;k<n;k++)
                 {  
                      if(IsSan(i,j,k)&&Color(i,j,k))
                          area=Area(i,j,k);
                      if (area>Max)                          
                          Max=area;
                 }
              }
         }
      printf("%.5lf",Max);
    }

发表于 2017-04-30 19:59:17 回复(0)
三重循环+叉积(√)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<bits/stdc++.h>
using namespace std;
struct node{
    char c;
    int x,y,z;
} z[1005];
double gao(int a,int b,int c){
    double x1=(z[a].x-z[b].x),x2=(z[c].x-z[b].x);
    double y1=(z[a].y-z[b].y),y2=(z[c].y-z[b].y);
    double z1=(z[a].z-z[b].z),z2=(z[c].z-z[b].z);
    return sqrt((y1*z2-z1*y2)*(y1*z2-z1*y2)+(z1*x2-x1*z2)*(z1*x2-x1*z2)+(x1*y2-y1*x2)*(x1*y2-y1*x2))/2;

}
int main()
{
   //  freopen("in","r",stdin);
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>z[i].c>>z[i].x>>z[i].y>>z[i].z;
    }
    double maxn=0;
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            for(int k=j+1;k<n;k++){
                if(z[i].c==z[j].c&&z[j].c==z[k].c)
                maxn=max(maxn,gao(i,j,k));
                if(z[i].c!=z[j].c&&z[i].c!=z[k].c&&z[j].c!=z[k].c){
                    maxn=max(maxn,gao(i,j,k));
                }
            }
        }
    }
    cout<<fixed<<setprecision(5);
    cout<<maxn<<endl;
    return 0;
}
发表于 2019-06-27 21:57:14 回复(0)
#include <iostream>
#include <cmath>
using namespace std;

double sideLength(double x1, double y1, double z1, double x2, double y2, double z2) {
    double temp = pow(x2 - x1, 2) + pow(y2 - y1, 2) + pow(z2 - z1, 2);
    return sqrt(temp);
}

int main(int argc, const char * argv[]) {
    int n;
    cin >> n;
    int p[n][4];
    for (int i = 0; i < n; i++) {
        char rgb;
        cin >> rgb;
        switch (rgb) {
            case 'R':
                p[i][0] = 0;
                break;
            case 'G':
                p[i][0] = 1;
                break;
            case 'B':
                p[i][0] = 2;
                break;
            default:
                break;
        }
        for (int j = 0; j < 3; j++) {
            cin >> p[i][j + 1];
        }
    }
    double maxS = 0;
    for (int i = 0; i < n - 2; i++) {
        for (int j =  i + 1; j < n - 1; j++) {
            for (int k = j + 1; k < n; k++) {
                bool con1 = p[i][0] == p[j][0] && p[i][0] == p[k][0];
                bool con2 = p[i][0] != p[j][0] && p[i][0] != p[k][0] && p[j][0] != p[k][0];
                if (!(con1 || con2)) {  //要么颜色都相同,要么颜色都不同。
                    continue;
                }
                //求三边长
                double a = sideLength(p[i][1], p[i][2], p[i][3], p[j][1], p[j][2], p[j][3]);
                double b = sideLength(p[i][1], p[i][2], p[i][3], p[k][1], p[k][2], p[k][3]);
                double c = sideLength(p[j][1], p[j][2], p[j][3], p[k][1], p[k][2], p[k][3]);
                double l = (a + b + c) / 2;    //半周长
                //海伦公式求面积
                double s = sqrt(l * (l - a) * (l - b) * (l - c));
                if (maxS < s) {
                    maxS = s;
                }
//                maxS = (maxS > s ? maxS : s);     //三目运算符,莫名其妙过不了!
            }
        }
    }
    printf("%.5f", maxS);
    return 0;
}
发表于 2017-10-20 23:12:10 回复(0)
iMO头像 iMO
发个php版本的:
<?php
$num = intval(trim(fgets(STDIN)));
for ($i = 0; $i < $num; $i++) {
    $rowArr[] = explode(' ', trim(fgets(STDIN)));
}
for ($i = 0, $maxArea = 0; $i < $num - 2; $i++) {
    for ($j = $i + 1; $j < $num - 1; $j++) {
        for ($k = $j + 1; $k < $num; $k++) {
            if (($rowArr[$i][0] == $rowArr[$j][0] && $rowArr[$j][0] == $rowArr[$k][0]) || ($rowArr[$i][0] != $rowArr[$j][0] && $rowArr[$i][0] != $rowArr[$k][0] && $rowArr[$j][0] != $rowArr[$k][0])) {
                $edge1Length = sqrt(pow($rowArr[$i][1] - $rowArr[$j][1], 2) + pow($rowArr[$i][2] - $rowArr[$j][2], 2) + pow($rowArr[$i][3] - $rowArr[$j][3], 2));
                $edge2Length = sqrt(pow($rowArr[$i][1] - $rowArr[$k][1], 2) + pow($rowArr[$i][2] - $rowArr[$k][2], 2) + pow($rowArr[$i][3] - $rowArr[$k][3], 2));
                $edge3Length = sqrt(pow($rowArr[$j][1] - $rowArr[$k][1], 2) + pow($rowArr[$j][2] - $rowArr[$k][2], 2) + pow($rowArr[$j][3] - $rowArr[$k][3], 2));
                if ($edge1Length + $edge2Length > $edge3Length && $edge1Length - $edge2Length < $edge3Length
                    && $edge1Length + $edge3Length > $edge2Length && $edge1Length - $edge3Length < $edge2Length
                    && $edge2Length + $edge3Length > $edge1Length && $edge2Length - $edge3Length < $edge1Length) {
                    $halfPerimeter = ($edge1Length + $edge2Length + $edge3Length) / 2;
                    $area = sqrt($halfPerimeter * ($halfPerimeter - $edge1Length) * ($halfPerimeter - $edge2Length) * ($halfPerimeter - $edge3Length));
                    if ($area > $maxArea || $maxArea == 0) {
                        $maxArea = $area;
                    }
                }
            }
        }
    }
}
echo sprintf('%.5f', $maxArea);
编辑于 2017-09-04 16:51:18 回复(0)
#include <iostream>
#include <algorithm>
#include <math.h>
  
using namespace std;
  
struct Point{
    char c;
    int x;
    int y;
    int z;
};
 
void run(int x1,int x2,int x3,int y1,int y2,int y3,int z1,int z2,int z3,double &area){
                long long x=(y2-y1)*(z3-z1)-(z2-z1)*(y3-y1);
                long long y=(z2-z1)*(x3-x1)-(x2-x1)*(z3-z1);
                long long z=(x2-x1)*(y3-y1)-(y2-y1)*(x3-x1);
                double s=sqrt((x*x)+(y*y)+(z*z))*0.5;
                area=max(area,s);
}
 
void calculate_area1(vector<Point>point,double &area){
    for(int i=0;i<point.size();i++){
        for(int j=i+1;j<point.size();j++){
            for(int k=j+1;k<point.size();k++){
                run(point[i].x,point[j].x,point[k].x,
                    point[i].y,point[j].y,point[k].y,
                    point[i].z,point[j].z,point[k].z,area);
            }
        }
    }
}
  
void calculate_area2(vector<Point>pointR,vector<Point>pointG,vector<Point>pointB,double &area){
    for(int i=0;i<pointR.size();i++){
        for(int j=0;j<pointG.size();j++){
            for(int k=0;k<pointB.size();k++){
                run(pointR[i].x,pointG[j].x,pointB[k].x,
                    pointR[i].y,pointG[j].y,pointB[k].y,
                    pointR[i].z,pointG[j].z,pointB[k].z,area);
            }
        }
    }
}
  
int main(){
    int N;
    cin>>N;
    Point temp;
    vector<Point>pointR;
    vector<Point>pointG;
    vector<Point>pointB;
    for(int i=0;i<N;i++){
        cin>>temp.c;
        cin>>temp.x;
        cin>>temp.y;
        cin>>temp.z;
        if(temp.c=='R') pointR.push_back(temp);
        if(temp.c=='G') pointG.push_back(temp);
        if(temp.c=='B') pointB.push_back(temp);
    }
    double area=0.0;
    calculate_area1(pointR,area);
    calculate_area1(pointG,area);
    calculate_area1(pointB,area);
    calculate_area2(pointR,pointG,pointB,area);
    printf("%.5f",area);
    return 0;
}
发表于 2017-07-10 18:18:48 回复(0)
//思路是统计3个颜色的数量,结构体排序,将相同颜色放一起。
//然后分别做选相同颜色,选择不同颜色的操作,输出结果
#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include <math.h>

using namespace std;

struct Point
{
	char c;
	double x, y, z;
};

bool cmp(Point p1, Point p2)
{
	return p1.c < p2.c;
}

double pointDistance(Point p1, Point p2)
{
	double distance = 0;
	distance = sqrt((p1.y - p2.y)*(p1.y - p2.y) + (p1.x - p2.x)*(p1.x - p2.x) + (p1.z - p2.z)*(p1.z - p2.z));
	return distance;
}

double area(Point p1, Point p2, Point p3)
{
	double area = 0;
	double a = 0, b = 0, c = 0, s = 0;
	a = pointDistance(p1, p2);
	b = pointDistance(p2, p3);
	c = pointDistance(p1, p3);
	s = 0.5*(a + b + c);
	area = sqrt(s*(s - a)*(s - b)*(s - c));
	return area;
}

int main()
{
	int n;
	while (cin >> n)
	{
		vector<Point> v(n);

		char c;
		int x, y, z;
		int cntR = 0, cntG = 0, cntB = 0;
		double ans = 0;

		for (int i = 0; i < n; i++)
		{
			cin >> v[i].c >> v[i].x >> v[i].y >> v[i].z;

			if (v[i].c == 'R')
				cntR++;
			if (v[i].c == 'G')
				cntG++;
			if (v[i].c == 'B')
				cntB++;
		}

		sort(v.begin(), v.end(), cmp);
		if (cntB >= 3)
		{
			for (int i = 0; i < cntB; i++)
			{
				for (int j = i + 1; j < cntB; j++)
				{
					for (int k = j + 1; k < cntB; k++)
					{
						ans = max(ans, area(v[i], v[j], v[k]));
					}
				}
			}


		}

		if (cntG >= 3)
		{
			for (int i = 0; i < cntG; i++)
			{
				for (int j = i + 1; j < cntG; j++)
				{
					for (int k = j + 1; k < cntG; k++)
					{
						ans = max(ans, area(v[cntB + i], v[cntB + j], v[cntB + k]));
					}
				}
			}


		}
		if (cntR >= 3)
		{
			for (int i = 0; i < cntR; i++)
			{
				for (int j = i + 1; j < cntR; j++)
				{
					for (int k = j + 1; k < cntR; k++)
					{
						ans = max(ans, area(v[cntB + cntG + i], v[cntB + cntG + j], v[cntB + cntG + k]));
					}
				}
			}
		}

		for (int i = 0; i < cntB; i++)
		{
			for (int j = cntB; j < cntB + cntG; j++)
			{
				for (int k = cntB + cntG; k < n; k++)
				{
					ans = max(ans, area(v[i], v[j], v[k]));
				}
			}
		}


		printf("%.5f\n", ans);
	}
}

发表于 2017-04-28 14:56:41 回复(0)
import sys
n=int(sys.stdin.readline().strip())
color=[]
cord=[]
for i in range(n):
    line=sys.stdin.readline().strip().split()
    color.append(line[0])
    cord.append(list(map(int,line[1:])))
def judge_SorD_color(a,b,c):
    if a==b==c:
        return True
    elif a!=b and b!=c and a!=c:
        return True
    else:
        return False
def cal_area(a,b,c):
    x1=b[0]-a[0]
    y1=b[1]-a[1]
    z1=b[2]-a[2]
    x2=c[0]-a[0]
    y2=c[1]-a[1]
    z2=c[2]-a[2]
    return (y1*z2-y2*z1)**2+(x2*z1-x1*z2)**2+(x1*y2-x2*y1)**2
maxarea=0
for i in range(n):
    for j in range(i+1,n):
        for k in range(j+1,n):
            if judge_SorD_color(color[i],color[j],color[k]):
                area=cal_area(cord[i],cord[j],cord[k])
                maxarea=max(area,maxarea)
print('%.5f'%(float(maxarea)**0.5/2))
发表于 2018-05-15 10:03:51 回复(0)
#!/usr/bin/env python
#-*- coding:utf8 -*-
class Node:                                       #构造Node类,每一个Node存储一行数据
    def __init__(self, l):
        self.c = l[0]
        self.x = int(l[1])
        self.y = int(l[2])
        self.z = int(l[3])

class Solution():
    def __init__(self, l):
        self.l = l
    def main(self, n):
        i, j, k = 0, 1, 2
        Max = 0
        for i in range(n):
            for j in range(i+1, n):
                for k in range(j+1, n):
                    if self.isSan(i, j, k) and self.isColour(i, j, k):
                        Area = self.getArea(i, j, k)
                        if Max < Area:
                            Max = Area
        return Max

    def isSan(self, i, j, k):                            
        a = self.getlength(i, j)
        b = self.getlength(i, k)
        c = self.getlength(k, j)
        if a < b+c and b < a+c and c < a+b:
            return True
        return False

    def getlength(self, i, j):
        x = abs(self.l[i].x - self.l[j].x)
        y = abs(self.l[i].y - self.l[j].y)
        z = abs(self.l[i].z - self.l[j].z)
        return (x*x+y*y+z*z)**0.5

    def isColour(self, i, j, k):
        if self.l[i].c == self.l[j].c and self.l[j].c == self.l[k].c:
            return True
        elif self.l[i].c != self.l[j].c and self.l[j].c != self.l[k].c and self.l[k].c != self.l[i].c:
            return True
        return False

    def getArea(self, i, j, k):
        a = self.getlength(i, j)
        b = self.getlength(i, k)
        c = self.getlength(k, j)
        s = 0.5 * (a+b+c)
        area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
        return area


if __name__ == '__main__':
    n = input()
    l = []
    for i in range(n):
        string = raw_input().split()
        node = Node(string)
        l.append(node)

    s = Solution(l)
    print("%.5f"%s.main(n))



发表于 2017-05-07 17:42:26 回复(1)
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
	"strings"
)

type point struct {
	color	byte
	x		int
	y		int
	z		int
}

// 计算两点之间的距离
func distance(A, B point) float64{
	return math.Sqrt(float64((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y) + (A.z-B.z)*(A.z-B.z)))
}

// 判断三个点颜色是否满足条件
func colorIsMathed(A, B, C point) bool {
	if A.color == B.color && B.color == C.color { // 三个点的颜色相同
		return true
	}else if A.color!=B.color && A.color!=C.color && B.color!=C.color { // 三个点的颜色都不相同
		return true
	}else {
		return false
	}
}

// 判断三个点是否能构成三角形
func isSan(A, B, C point) bool {
	a := distance(A, B)
	b := distance(A, C)
	c := distance(B, C)
	if a<(b+c) && b<(a+c) && c<(a+b) && a>math.Abs(b-c) && b>math.Abs(a-c) && c>math.Abs(a-b){
		return true
	}
	return false
}

// 计算三角形面积
func getArea(A, B, C point) float64 {
	a := distance(A, B)
	b := distance(A, C)
	c := distance(B, C)
	p := (a+b+c) / 2
	return math.Sqrt(p*(p-a) * (p-b) * (p-c))
}

func main() {
	var n int
	fmt.Scan(&n)
	var list []point

	input := bufio.NewScanner(os.Stdin)
	for i := 0; i < n; i++ {
		p := point{}
		input.Scan()
		s := strings.Split(input.Text(), " ")
		a := []byte(s[0])
		res := []int{}
		for i := 0; i < len(s); i++ {
			num, _ := strconv.Atoi(s[i])
			res = append(res, num)
		}
		p.color = a[0]
		p.x = res[1]
		p.y = res[2]
		p.z = res[3]
		list = append(list, p)
	}

	maxArea := 0.0
	area := 0.0

	for i := 0; i < n; i++ {
		for j := i+1; j < n; j++ {
			for k := j+1; k < n; k++ {
				A := list[i]
				B := list[j]
				C := list[k]

				if isSan(A, B, C) && colorIsMathed(A, B, C) {
					area = getArea(A, B, C)
				}
				if area > maxArea {
					maxArea = area
				}
			}
		}
	}
	fmt.Printf("%.5f",maxArea)
}

发表于 2022-03-29 16:32:23 回复(0)
import math

def is_color(a,b,c):
    if a==b==c or(a!=b and a!=c and b!=c):
        return True
    else:
        return False

def cross_product(a,b,c):
    """
    S = |AB x AC|/2
    """
    ab = [b[i]-a[i] for i in range(3)]
    ac = [c[i]-a[i] for i in range(3)]
    i = ab[1]*ac[2]-ab[2]*ac[1]
    j = ab[2]*ac[0]-ab[0]*ac[2]
    k = ab[0]*ac[1]-ab[1]*ac[0]
    S = math.sqrt(i**2+j**2+k**2) / 2
    return S

N = int(input().strip())
points = []
colors = []
res = 0
for _ in range(N):
    line = input().strip().split()
    colors.append(line[0])
    points.append([int(x) for x in line[1:]])
for i in range(N):
    for j in range(i+1, N):
        for k in range(j+1, N):
            if is_color(colors[i], colors[j], colors[k]):
                res = max(res, cross_product(points[i], points[j], points[k]))

# print(f'{res:.5f}')
print('%.5f' % res)

发表于 2020-03-28 20:38:22 回复(0)
这题是真的鬼畜 太麻烦了
发表于 2020-03-14 00:01:42 回复(0)
import math

class Point(object):
    '''定义三个点'''

    def __init__(self, c, x, y, z):
        self.c = c
        self.x = x
        self.y = y
        self.z = z


def valid(l1, l2, l3):
    token = [l1, l2, l3]
    token.sort()
    '''判断三个点是否能构成三角形(两边之和大于第三边)'''
    return token[0] + token[1] > token[2]


def cal_len(p1, p2):
    '''求两点之间的距离'''
    l = pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2) + pow(p1.z - p2.z, 2)
    return math.sqrt(l)


def cal_s(c1, c2, c3):
    '''求空间中三个点组成的三角形的面积'''
    l1 = cal_len(c1, c2)
    l2 = cal_len(c2, c3)
    l3 = cal_len(c3, c1)
    ans = 0
    if valid(l1, l2, l3):
        p = (l1 + l2 + l3) / 2
        token = math.sqrt(p * (p - l1) * (p - l2) * (p - l3))
        ans = max(token, ans)
    return ans

def solution(N,nums):
    '''计算三角形的最大面积'''
    ans=0
    for i in range(N):
        for j in range(i + 1, N):
            for k in range(j + 1, N):
                if (nums[i].c == nums[j].c == nums[k].c or len(set([nums[i].c, nums[j].c, nums[k].c])) == 3):
                    '''判断空间中的三个点颜色是否都相同或都不相同'''
                    ans = max(ans, cal_s(nums[i], nums[j], nums[k]))
    return ans

'''主程序'''
N = int(input())
nums = []
for i in range(N):
    c, x, y, z = input().strip().split()
    nums.append(Point(c, int(x), int(y), int(z)))
ans=solution(N,nums)
print('{:.5f}'.format(ans))

发表于 2019-08-26 17:01:23 回复(0)
clc;clear;close all;
N=input('');
point={};
%%元胞数组
for i=1:N
point{i}=input('','s');
end
%%排列组合
unin=nchoosek(point,3);
len=length(unin);
tri_len=zeros(len,3);
%%求解排列组合中三角形边长
for i=1:len
    A=unin{i,1};
    B=unin{i,2};
    C=unin{i,3};
    color(i,1)=A(1);
     color(i,2)=B(1);
      color(i,3)=C(1);
      A(1)=0;
      B(1)=0;
      C(1)=0;
      A=str2num(A);
       B=str2num(B);
        C=str2num(C);
    tri_len(i,1)=sqrt((A(1)-B(1))^2+(A(2)-B(2))^2+(A(3)-B(3))^2);
    tri_len(i,2)=sqrt((A(1)-C(1))^2+(A(2)-C(2))^2+(A(3)-C(3))^2);
    tri_len(i,3)=sqrt((C(1)-B(1))^2+(C(2)-B(2))^2+(C(3)-B(3))^2);
end
%%海伦公式求面积
p=sum(tri_len')/2;
for i=1:len
    area(i)=sqrt(p(i)*(p(i)-tri_len(i,1))*(p(i)-tri_len(i,2))*(p(i)-tri_len(i,3)));
end
%%判断面积最大的是否满足颜色要求
out=0;
while(out==0)
areamax=max(area);
index=find(area==areamax);
     if (color(index,1)==color(index,2))&&(color(index,1)==color(index,3))&&(color(index,2)==color(index,3))
    out=areamax;
   break
  else
     if (color(index,1)~=color(index,2))&&(color(index,1)~=color(index,3))&&(color(index,2)~=color(index,3))
         out=areamax;
         break
     else
     area(index)=0;
     out=0;
  end
  end
end
out=num2str(out,'%.5f');
fprintf('%s',out); 
用matlab编写了一段程序,本机软件可以运行通过,牛客网报错,请各位大牛指导一下,哪里有问题
发表于 2019-08-22 10:08:28 回复(0)
//参考第一个答案,思路很明确
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;

struct node {
    char c;
    int x, y, z;

};
vector<node> V;
double Max = 0;
//计算两点间的距离

double L(int i, int j)
{
    return sqrt(double((V[i].x - V[j].x) * (V[i].x - V[j].x) + (V[i].y - V[j].y) * (V[i].y - V[j].y) + (V[i].z - V[j].z) * (V[i].z - V[j].z)));
}
//计算能否构成三角形
bool Three(int i, int j, int k)
{
    double a = L(i, j);
    double b = L(j, k);
    double c = L(i, k);
    if (a < (b + c) && b < (a + c) && c < (a + b))
        return true;
    else return false;
}
//判断颜色是否相同
bool Color(int i, int j, int k)
{
    if (V[i].c == V[j].c && V[j].c == V[k].c) return true;
    else if (V[i].c != V[j].c&& V[j].c != V[k].c) return true;
    else return false;
}

//计算面积
double Area(int i, int j, int k)
{
    double a = L(i, j);
    double b = L(i, k);
    double c = L(j, k);
    double p = (a + b + c) / 2;
    return sqrt(p * (p - a) * (p - b) * (p - c));
}
int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        node t;
        cin >> t.c >> t.x >> t.y >> t.z;
        V.push_back(t);
    
    }
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n; j++)
            for (int k = j + 1; k < n; k++)
            {
                if (Three(i, j, k) && Color(i, j, k))
                {
                    double area = Area(i, j, k);
                    Max = max(Max, area);
                }
                else continue;
            }
    printf("%.5lf", Max);

}

发表于 2019-08-19 10:29:14 回复(0)