Problem:
凸 n 角形の面積

凸 n 角形（すべての頂点の内角が 180 度未満である多角形、要するにへこんでいない多角形のこと）の頂点の座標を読んで、その面積を出力するプログラムを作成してください。頂点には辺のつながりの順序に従って頂点 1、頂点 2、頂点 3、‥‥頂点 n という名前がついています。

ただし、 n は 3 以上 20 以下とします。また、次の、三角形の 3 辺の長さ a, b, c から面積 S を求める公式を使ってもかまいません。

入力

入力は以下の形式で与えられます。

x1,y1
x2,y2
:
xn,yn

xi, yi はそれぞれ頂点 i の x 座標, y 座標を表す実数です。

出力

面積 S （実数）を１行に出力します。
出力は 0.000001 以下の誤差を含んでもかまいません。

Sample Input

0.0,0.0
0.0,1.0
1.0,1.0
2.0,0.0
1.0,-1.0

Output for the Sample Input

2.500000

Solution in JAVA (judge verdict: Accepted)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;


public class Main {
	private	static	BufferedReader	br = null;

	static {
		br = new BufferedReader(new InputStreamReader(System.in));
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		double[]	point   = null;
		MyPolygon	polygon = new MyPolygon();

		while ((point = parsePoint()) != null) {
			polygon.AddEx(point);
		}

		System.out.printf("%.6f\n", polygon.calcSum());
	}

	private static double[] parsePoint() {
		String		line  = null;
		String[]	split = null;
		double[]	point = null;

		if ((line = parseStdin()) != null) {
			if (!line.isEmpty()) {
				split    = line.split(",");
				point    = new double[4];
				point[0] = Double.parseDouble(split[0]);
				point[1] = Double.parseDouble(split[1]);
			}
		}

		return point;
	}

	private static String parseStdin() {
		String	stdin = null;

		try {
			stdin = br.readLine();
		}
		catch (IOException e) {}

		return stdin;
	}
}

class MyPolygon extends ArrayList<double[]> {
	private	static	double[]	oPos = null;

	public void AddEx(double[] element) {
		int	len = size();

		if (len == 0) {
			oPos = element;
		}
		else {
			if (element[1] < oPos[1] || (element[1] == oPos[1] && element[0] < oPos[0])) {
				oPos = element;
			}
		}

		add(element);
		Collections.sort(this, new MyComparator());
	}

	public void clearEx() {
		clear();
		oPos = null;
	}

	public double calcSum() {
		int			max = size();
		double		z   = 0.0;
		double		sum = 0.0;
		double[][]	tmp = new double[2][];
		double[]	len = new double[3];

		if (max >= 3) {
			for (int n = 1; n < max - 1; n++) {
				tmp[0] = get(n);
				tmp[1] = get(n + 1);
				len[0] = tmp[0][2];
				len[1] = tmp[1][2];
				len[2] = Math.sqrt(Math.pow(tmp[0][1] - tmp[1][1], 2.0) + Math.pow(tmp[0][0] - tmp[1][0], 2.0));
				z      = (len[0] + len[1] + len[2]) / 2.0;
				sum   += Math.sqrt(z*(z - len[0])*(z - len[1])*(z - len[2]));
			}
		}

		return sum;
	}

	class MyComparator implements Comparator<double[]> {
		public int compare(double[] pos1,double[] pos2){
			pos1[2] = Math.sqrt(Math.pow(pos1[1] - oPos[1], 2.0) + Math.pow(pos1[0] - oPos[0], 2.0));
			pos1[3] = Math.atan2(pos1[1] - oPos[1], pos1[0] - oPos[0]);
			pos2[2] = Math.sqrt(Math.pow(pos2[1] - oPos[1], 2.0) + Math.pow(pos2[0] - oPos[0], 2.0));
			pos2[3] = Math.atan2(pos2[1] - oPos[1], pos2[0] - oPos[0]);

			return (pos1[3] == pos2[3]) ? (pos1[2] == pos2[2]) ? 0 : (pos1[2] < pos2[2]) ? -1 : 1 : (pos1[3] < pos2[3]) ? -1 : 1;
		}
	}
}