Problem:
Distance

For given two segments s1 and s2, print the distance between them.

s1 is formed by end points p0 and p1, and
s2 is formed by end points p2 and p3.

Input

The entire input looks like:

q (the number of queries)
1st query
2nd query
...
qth query

Each query consists of integer coordinates of end points of s1 and s2 in the following format:

xp0 yp0 xp1 yp1 xp2 yp2 xp3 yp3

Output

For each query, print the distance. The output values should be in a decimal fraction with an error less than 0.00000001.

Constraints

1 ≤ q ≤ 1000

-10000 ≤ xpi, ypi ≤ 10000

p0 ≠ p1 and
p2 ≠ p3.

Sample Input

3
0 0 1 0 0 1 1 1
0 0 1 0 2 1 1 2
-1 0 1 0 0 1 0 -1

Sample Output

1.0000000000
1.4142135624
0.0000000000

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;

namespace geometry
{
	public class Point{
		public double x, y;
		public Point(){
			this.x = this.y = 0;
		}

		public Point(double x, double y){
			this.x = x;
			this.y = y;
		}

		public static Point operator+(Point p1, Point p2){
			return new Point (p1.x + p2.x, p1.y + p2.y);
		}

		public static Point operator-(Point p1, Point p2){
			return new Point (p1.x - p2.x, p1.y - p2.y);
		}

		public static Point operator*(Point p1, double a){
			return new Point (p1.x * a, p1.y * a);
		}

		public static Point operator/(Point p1, double a){
			return new Point (p1.x / a, p1.y / a);
		}

		public double norm(){
			return this.x * this.x + this.y * this.y;
		}

		public double abs(){
			return Math.Sqrt(norm()); 
		}

		public Point Clone(){
			Point clone = new Point (this.x, this.y);
			return clone;
		}
	}

	public class Line{
		public Point p1, p2;
		public Line(){
			this.p1 = new Point ();
			this.p2 = new Point ();
		}

		public Line(double p1x, double p1y, double p2x, double p2y){
			this.p1 = new Point(p1x, p1y);
			this.p2 = new Point(p2x, p2y);
		}

		public Line(Point p1, Point p2){
			this.p1 = p1.Clone();
			this.p2 = p2.Clone();
		}

		public Line Clone(){
			Line clone = new Line (this.p1, this.p2);
			return clone;
		}
	}

	public class Circle{
		public Point c;
		public double r;
		public Circle(){
			this.c = new Point ();
			this.r = 0.0;
		}

		public Circle(double cx, double cy, double r){
			this.c.x = cx;
			this.c.y = cy;
			this.r = r;
		}

		public Circle(Point c, double r){
			this.c = c.Clone();
			this.r = r;
		}

		public Circle Clone(){
			Circle clone = new Circle (this.c, this.r);
			return clone;
		}
	}

	class MainClass{
		static bool is_equal(double a, double b){
			if (Math.Abs (a - b) < 0.000001) {
				return true;
			} else {
				return false;
			}
		}

		static double dot(Point v1, Point v2){
			return v1.x * v2.x + v1.y * v2.y;
		}

		static double cross(Point v1, Point v2){
			return v1.x * v2.y - v1.y * v2.x;
		}

		// ??´?????????
		static bool is_orthogonal(Line s1, Line s2){
			return is_equal(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
		}

		// ????????????
		static bool is_parallel(Line s1, Line s2){
			return is_equal(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
		}

		// ????????????
		static bool is_intersect(Line s1, Line s2){
			return ccw(s1.p1, s1.p2, s2.p1) * ccw(s1.p1, s1.p2, s2.p2) <= 0 && ccw(s2.p1, s2.p2, s1.p1) * ccw(s2.p1, s2.p2, s1.p2) <= 0;
		}

		// ?°???±??¢??°
		static Point project(Line s, Point p){
			Point base_v = s.p2 - s.p1;
			double r = dot (p - s.p1, base_v) / base_v.norm ();
			return s.p1 + base_v * r;
		}

		// ????°???¢??°
		static Point reflect(Line s, Point p){
			return p + (project(s, p) - p) * 2;
		}

		// ???????¨???????
		static int ccw(Point p0, Point p1, Point p2){
			Point v1 = p1 - p0;
			Point v2 = p2 - p0;
			if (cross (v1, v2) > 0.000001) {
				return 1;
			}
			if (cross (v1, v2) < -0.000001) {
				return -1;
			}
			if (dot (v1, v2) < -0.000001) {
				return 2;
			}
			if (v1.norm() < v2.norm()) {
				return -2;
			}
			return 0;
		}

		// 2??????????????¢????±???????
		static double get_distance_p2p(Point p1, Point p2){
			return (p2 - p1).abs();
		}
		// ??´?????¨???????????¢????±???????
		static double get_distance_l2p(Line l, Point p){
			return Math.Abs (cross (l.p2 - l.p1, p - l.p1)) / (l.p2 - l.p1).abs ();
		}

		// ????????¨???????????¢????±???????
		static double get_distance_s2p(Line s, Point p){
			if (dot (s.p2 - s.p1, p - s.p1) < 0.0) {
				return (p - s.p1).abs ();
			} else if (dot (s.p1 - s.p2, p - s.p2) < 0.0) {
				return (p - s.p2).abs ();
			}
			return get_distance_l2p (s, p);
		}

		// ????????¨??????????????¢????±???????
		static double get_distance_s2s(Line s1, Line s2){
			if (is_intersect(s1, s2)) {
				return 0.0;
			}
			return Math.Min (Math.Min (get_distance_s2p (s1, s2.p1), get_distance_s2p (s1, s2.p2)), Math.Min (get_distance_s2p (s2, s1.p1), get_distance_s2p (s2, s1.p2)));
		}

		static double[] input_line(){
			string[] s = Console.ReadLine().Split(' ');
			double[] d = s.Select(i => double.Parse(i)).ToArray();
			return d;
		}

		// ?°???±
		static void CGL_1_A(){
			double[] d = input_line ();
			Line l = new Line(d[0], d[1], d[2], d[3]);

			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] p_pos = input_line ();
				Point p1 = new Point (p_pos[0], p_pos[1]);
				Point p2 = project (l, p1);
				Console.WriteLine ("{0} {1}", p2.x, p2.y);
			}
		}

		// ????°?
		static void CGL_1_B(){
			double[] d = input_line ();
			Line l = new Line(d[0], d[1], d[2], d[3]);

			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] p_pos = input_line ();
				Point p1 = new Point (p_pos [0], p_pos [1]);
				Point p2 = reflect (l, p1);
				Console.WriteLine ("{0} {1}", p2.x, p2.y);
			}
		}

		// ???????¨???????
		static void CGL_1_C(){
			double[] d = input_line ();
			Point p0 = new Point (d [0], d [1]);
			Point p1 = new Point (d [2], d [3]);

			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] p_pos = input_line ();
				Point p2 = new Point (p_pos [0], p_pos [1]);
				string s;
				int c = ccw (p0, p1, p2);
				if (c == 1) {
					s = "COUNTER_CLOCKWISE";
				} else if (c == -1) {
					s = "CLOCKWISE";
				} else if (c == 2) {
					s = "ONLINE_BACK";
				} else if (c == -2) {
					s = "ONLINE_FRONT";
				} else {
					s = "ON_SEGMENT";
				}
				Console.WriteLine ("{0}", s);
			}
		}

		// ??´????????´???/????????????
		static void CGL_2_A(){
			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] s_pos = input_line ();
				Line s1 = new Line(s_pos[0], s_pos[1], s_pos[2], s_pos[3]);
				Line s2 = new Line(s_pos[4], s_pos[5], s_pos[6], s_pos[7]);
				if (is_parallel (s1, s2)) {
					Console.Write ("2\n");
				} else if (is_orthogonal (s1, s2)) {
					Console.Write ("1\n");
				} else {
					Console.Write ("0\n");
				}
			}
		}

		// ?????????????????????
		static void CGL_2_B(){
			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] s_pos = input_line ();
				Line s1 = new Line(s_pos[0], s_pos[1], s_pos[2], s_pos[3]);
				Line s2 = new Line(s_pos[4], s_pos[5], s_pos[6], s_pos[7]);

				if (is_intersect (s1, s2)) {
					Console.Write ("1\n");
				} else {
					Console.Write ("0\n");
				}
			}
		}

		// ?????¢
		static void CGL_2_D(){
			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] s_pos = input_line ();
				Line s1 = new Line(s_pos[0], s_pos[1], s_pos[2], s_pos[3]);
				Line s2 = new Line(s_pos[4], s_pos[5], s_pos[6], s_pos[7]);

				Console.Write ("{0}\n", get_distance_s2s(s1, s2));
			}
		}

		public static void Main (string[] args){
			// ?°???±
			//CGL_1_A ();
			// ????°?
			//CGL_1_B ();
			// ???????¨???????
			//CGL_1_C ();
			// ??´????????´???/????????????
			//CGL_2_A ();
			// ?????????????????????
			//CGL_2_B ();
			// ?????¢
			CGL_2_D ();
		}
	}
}