Problem:
Problem D: Exportation in Space

In an era of space travelling, Mr. Jonathan A. Goldmine exports a special
material named "Interstellar Condensed Powered Copper". A piece of it consists
of several spheres floating in the air. There is strange force affecting between
the spheres so that their relative positions of them are not changed. If you
move one of them, all the others follow it.

Example of ICPC (left: bare, right: shielded)

To transport ICPCs between planets, it needs to be shielded from cosmic
rays. It will be broken when they hit by strong cosmic rays. Mr. Goldmine needs
to wrap up each ICPC pieces with anti-cosmic-ray shield, a paper-like material
which cuts all the cosmic rays. To save cost, he wants to know the minimum area
of the shield he needs to wrap an ICPC piece up.

Note that he can't put the shield between the spheres of an ICPC because
it affects the force between the spheres. So that the only way to shield it is
to wrap the whole ICPC piece by shield.

Mr. Goldmine asked you, an experienced programmer, to calculate the
minimum area of shield for each material.

You can assume that each sphere in an ICPC piece is a point, and you can
ignore the thickness of the shield.

Input

Each file consists of one test case, which has the information of one
ICPC piece. A test case starts with a line with an integer N (4 <= N
<= 50), denoting the number of spheres in the piece of the test case. Then N
lines follow. The i-th line of them describes the position of the i-th
sphere. It has 3 integers xi, yi and
zi (0 <= x, y, z <= 100),
separated by a space. They denote the x, y and z
coordinates of the i-th sphere, respectively.

It is guaranteed that there are no data all of whose spheres are on the
same plane, and that no two spheres in a data are on the same coordinate.

Output

For each input, print the area of the shield Mr. Goldmine needs. The
output value should be in a decimal fraction and should not contain an error greater than 0.001.

Sample Input 1

4
0 0 0
0 0 1
0 1 0
1 0 0

Output for the Sample Input 1

2.366

Sample Input 2

8
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

Output for the Sample Input 2

6.000

Solution in JAVA (judge verdict: Accepted)

import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;
import static java.lang.Math.*;

// Exportation in Space
// 2012/12/13
public class Main{
	Scanner sc=new Scanner(System.in);

	double EPS=1e-6;
	int n;
	P[] ps;

	void run(){
		n=sc.nextInt();
		ps=new P[n];
		for(int i=0; i<n; i++){
			double x=sc.nextInt();
			double y=sc.nextInt();
			double z=sc.nextInt();
			ps[i]=new P(x, y, z);
		}
		solve();
	}

	void solve(){
		for(int i=0; i<n; i++){
			P d=new P(random()*EPS, random()*EPS, random()*EPS);
			ps[i]=ps[i].add(d);
		}

		P[][] ch=convexHull(ps);
		double sum=0;
		for(P[] ps : ch){
			double a=ps[0].sub(ps[1]).abs();
			double b=ps[1].sub(ps[2]).abs();
			double c=ps[2].sub(ps[0]).abs();
			sum+=area(a, b, c);
		}
		println(String.format("%.12f", sum));
	}

	double area(double a, double b, double c){
		double s=(a+b+c)/2;
		return sqrt(s*(s-a)*(s-b)*(s-c));
	}

	P[][] convexHull(P[] ps){
		int n=ps.length;

		int[][] vs=new int[n][n];
		List<int[]> crt=new ArrayList<int[]>();
		crt.add(new int[]{0, 1, 2});
		crt.add(new int[]{2, 1, 0});

		for(int i=3; i<n; i++){
			List<int[]> next=new ArrayList<int[]>();
			for(int[] t : crt){
				int v=ps[t[1]].sub(ps[t[0]]).det(ps[t[2]].sub(ps[t[0]]))
						.dot(ps[i].sub(ps[t[0]]))<0?-1:1;
				if(v<0)
					next.add(t);
				for(int j=0; j<3; j++){
					if(vs[t[(j+1)%3]][t[j]]==0){
						vs[t[j]][t[(j+1)%3]]=v;
					}else{
						if(vs[t[(j+1)%3]][t[j]]!=v){
							if(v>0)
								next.add(new int[]{t[j], t[(j+1)%3], i});
							else
								next.add(new int[]{t[(j+1)%3], t[j], i});
						}
						vs[t[(j+1)%3]][t[j]]=0;
					}
				}
			}
			crt=next;
		}

		P[][] pss=new P[crt.size()][3];
		for(int i=0; i<pss.length; i++){
			for(int j=0; j<3; j++)
				pss[i][j]=ps[crt.get(i)[j]];
		}
		return pss;
	}

	class P{
		double x, y, z;

		P(double x, double y, double z){
			this.x=x;
			this.y=y;
			this.z=z;
		}

		P add(P p){
			return new P(x+p.x, y+p.y, z+p.z);
		}

		P sub(P p){
			return new P(x-p.x, y-p.y, z-p.z);
		}

		P mul(double m){
			return new P(x*m, y*m, z*m);
		}

		P div(double d){
			return new P(x/d, y/d, z/d);
		}

		double abs(){
			return sqrt(abs2());
		}

		double abs2(){
			return x*x+y*y+z*z;
		}

		double dot(P p){
			return x*p.x+y*p.y+z*p.z;
		}

		P det(P p){
			return new P(y*p.z-z*p.y, z*p.x-x*p.z, x*p.y-y*p.x);
		}
	}

	void println(String s){
		System.out.println(s);
	}

	public static void main(String[] args){
		new Main().run();
	}
}