Problem:
Spiral Footrace

Let us enjoy extraordinary footraces at an athletic field.
Before starting the race, small flags representing checkpoints are set up
at random on the field. Every runner has to pass all the checkpoints one by
one in the spiral order specified below.
The starting point is the southwest corner of the athletic field.

At the starting point, runners are facing north.
During the race, they run clockwise in a spiral passing
every checkpoint as illustrated in the following figure.
When moving from one flag to the next, they take a straight path.
This means that the course of a race is always piecewise linear.

Upon arriving at some flag, a runner has to determine the next flag
among those that are not yet visited.
That flag shall be the one at the smallest angle to the right of the direction
that the runner is facing. When more than two flags are on the same straight
line, the runner visits the nearest flag first.
The goal position is the place of the last visited flag.

Your job is to write a program that calculates the length of the course from
the starting point to the goal, supposing that the course consists of
line segments connected by flags.
The position of each flag is given by a coordinate pair
(xi, yi), which is limited
to the first quadrant. The starting point is fixed to the origin (0, 0) where a
flag is always set up.

Input

The input contains multiple data sets, each representing a collection of
flag positions for a footrace. A data set is given in the following
format.

n

x1 y1

x2 y2

...

xn yn

Here, n is the number of flag positions (1 <= n <= 400).
The position of the i-th flag is given by
(xi, yi), where
xi and yi are integers
in meter between 0 and 500 inclusive.
There may be white spaces (blanks and/or tabs) before, in between, or after
xi and yi.
Once a certain
coordinate pair (xi, yi) is given,
the same one will not appear later in the data set, and the origin (0, 0)
will not appear either.

A data set beginning with n = 0 indicates end of the input.

Output

For each data set, your program should output the length of the running course
in meter. Each length should appear on a separate line, with
one digit to the right of the decimal point, after rounding it to one
decimal place.

Sample Input

8
60 70
20 40
50 50
70 10
10 70
80 90
70 50
100 50
5
60 50
0 80
60 20
10 20
60 80
0

Output for the Sample Input

388.9
250.0

Solution in JAVA (judge verdict: Accepted)

import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.*;
 
public class Main {
    Scanner in = new Scanner(System.in);
    public static void main(String[] args) {
        new Main();
    }
 
    public Main() {
        while(true){
            int n = in.nextInt();
            if(n==0)break;
            new AOJ1107().doIt(n);
        }
    }
     
    class AOJ1107{
    	double EPS = 1.0e-8;
    	int comp(double x,double y){
    		if(Math.abs(x-y)<EPS)return 0;
    		if(x<y)return -1;
    		return 1;
    	}
    	
        void doIt(int n){
            Point2D[] p = new Point2D[n];
            for(int i=0;i<n;i++)p[i] = new Point2D.Double(in.nextDouble(), in.nextDouble());
            boolean[] used = new boolean[n];
            double result = 0;
            Point2D before = new Point2D.Double(0,-1);
            Point2D now = new Point2D.Double(0,0);
            int visit = 0;
            while(visit!=n){
                double max = Integer.MIN_VALUE;
                double len = Double.MAX_VALUE;
                int index = -1;
                for(int i=0;i<n;i++)if(!used[i]){
                    //内積
                    double ccw = dot(sub(now, before),sub(p[i],now));
                    double res = now.distance(p[i]);
//                  System.out.println(sub(now, before));
//                  System.out.println(sub(p[i], now));
                    ccw /= sub(now,before).distance(0,0);
                    ccw /= sub(p[i],now).distance(0,0);
//                  System.out.println("CCW " + ccw+" "+i+" "+p[i]);
                    int diff = comp(max, ccw);
                    if((diff<0)||(diff==0&&res<len)){
                        max = ccw;
                        index = i;
                        len = res;
                    }
                }
 
//              System.out.println(sub(now, before));
//              System.out.println(sub(p[index], now));
                used[index] = true;
//              System.out.println("CCW "+index+" "+p[index]);
                result += p[index].distance(now);
                before = now;
                now = p[index];
                visit++;
            }
            System.out.printf("%.1f\n",result);
        }
        double dot(Point2D p1,Point2D p2){
            return p1.getX()*p2.getX()+p1.getY()*p2.getY();
        }
        Point2D sub(Point2D p1,Point2D p2){
            return new Point2D.Double(p1.getX()-p2.getX(),p1.getY()-p2.getY());
        }
    }
}