Problem:
Score : 500 points

Problem Statement

#nck {
width: 30px;
height: auto;
}

Snuke received a triangle as a birthday present.
The coordinates of the three vertices were (x_1, y_1), (x_2, y_2), and (x_3, y_3).

He wants to draw two circles with the same radius inside the triangle such that the two circles do not overlap (but they may touch).
Compute the maximum possible radius of the circles.

Constraints

0 ≤ x_i, y_i ≤ 1000

The coordinates are integers.

The three points are not on the same line.

Input

The input is given from Standard Input in the following format:

x_1 y_1
x_2 y_2
x_3 y_3

Output

Print the maximum possible radius of the circles.
The absolute error or the relative error must be at most 10^{-9}.

Sample Input 1

0 0
1 1
2 0

Sample Output 1

0.292893218813

Sample Input 2

3 1
1 5
4 9

Sample Output 2

0.889055514217

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;//リストの使用
using System.Collections.Generic;
class Program
{
static long test = 0;//二部探索回数のメモ
static decimal maxLength = 0;
static decimal radius = 0;

	static void Main()
	{
		string[] input = Console.ReadLine().Split(' ');
    Vector2 pointA = new Vector2(decimal.Parse(input[0]), decimal.Parse(input[1]));
    string[] inputb = Console.ReadLine().Split(' ');
    Vector2 pointB = new Vector2(decimal.Parse(inputb[0]), decimal.Parse(inputb[1]));
    string[] inputc = Console.ReadLine().Split(' ');
    Vector2 pointC = new Vector2(decimal.Parse(inputc[0]), decimal.Parse(inputc[1]));

    maxLength = Math.Max(Vector2.Distance(pointA, pointB), Vector2.Distance(pointA, pointC));
    maxLength = Math.Max(maxLength, Vector2.Distance(pointB, pointC));
    radius = Vector2.InscribedCircleRadius(pointA, pointB, pointC);
      
    Console.WriteLine(Search(0, 9999));
	}

  static decimal Search(decimal min, decimal max)//二分探索法で最大値を求める
  {
    while (true)
    {
      test++;
      //Console.WriteLine(min+" "+max);
      decimal mid = min + (max - min) / 2;
      if(Check(mid)) min = mid;//さらに大きくても成り立つかも
      else max = mid;

      if(test > 10000)//二分探索を10000回行ったら終了
      {
        if(Check(max)) 
        {
          return max;//最大値で成り立つかの確認を優先
        }
        else
        {
          return min;
        }
      break;
      }  
    }
  }

  static bool Check(decimal testNum)
  {
    if(maxLength * (radius-testNum) >= radius * testNum * 2) return true;
    
    return false;
  }
  
}

class Vector2//2次元ベクトル
{
static decimal EPS = 1e-10m;//小数誤差比較

  public Vector2 (decimal X, decimal Y)
  {
    this.x = X;
    this.y = Y;
  }

  public decimal x {private set; get;}
  public decimal y {private set; get;}

  public static Vector2 operator + (Vector2 ob1, Vector2 ob2)//ベクトルの基本演算
  {
    return new Vector2 (ob1.x + ob2.x, ob1.y + ob2.y);
  }
  public static Vector2 operator - (Vector2 ob1, Vector2 ob2)
  {
    return new Vector2 (ob1.x - ob2.x, ob1.y - ob2.y);
  }
  public static Vector2 operator * (Vector2 ob, decimal scalar)
  {
    return new Vector2 (ob.x * scalar, ob.y * scalar);
  }
  public static Vector2 operator * (decimal scalar, Vector2 ob)
  {
    return new Vector2 (ob.x * scalar, ob.y * scalar);
  }
  public static Vector2 operator / (Vector2 ob, decimal scalar)
  {
    return new Vector2 (ob.x / scalar, ob.y / scalar);
  }

  public decimal Length()//ベクトルの長さの2乗
  {
    return x * x + y * y;
  }
  public static decimal Distance(Vector2 ob1, Vector2 ob2)//2点間の距離
  {
    return (decimal)Math.Sqrt((double)((ob1.x-ob2.x) * (ob1.x-ob2.x) + (ob1.y-ob2.y) * (ob1.y-ob2.y)));
  }
  public static decimal DotProduct(Vector2 ob1, Vector2 ob2)//内積
  {
    return ob1.x * ob2.x + ob1.y * ob2.y;
  }
  public static decimal CrossProduct(Vector2 ob1, Vector2 ob2)//外積。第2引数が反時計回り側で正。
  {
    return ob1.x * ob2.y - ob1.y * ob2.x;
  }
  public static decimal Arg(Vector2 p)//x軸に対する偏角
  {
    return (decimal)Math.Atan2((double)p.y, (double)p.x);
  }
  public static Vector2 PoralCoordinate(decimal radius, decimal angle)//長さと座標から極座標にする
  {
    return new Vector2(radius * (decimal)Math.Cos((double)angle), radius * (decimal)Math.Sin((double)angle));
  }

  public static Vector2 Projection(Vector2 beginPoint, Vector2 endPoint, Vector2 point)//点の射影
  {
    Vector2 segment = endPoint - beginPoint;
    decimal ratio = Vector2.DotProduct(point - beginPoint, segment) / segment.Length();
    return beginPoint + segment * ratio;//始点にたす
  }

public static long WhereVector(Vector2 beginPoint, Vector2 endPoint, Vector2 point)
  {//ベクトルに対する点の位置
    Vector2 segment = endPoint - beginPoint;
    Vector2 aimVec = point - beginPoint;
    if(Vector2.CrossProduct(segment, aimVec) > EPS)
      return 1;//反時計回り側
    else if(Vector2.CrossProduct(segment, aimVec) < -EPS)
      return 2;//時計回り側
    else if(Vector2.DotProduct(segment, aimVec) < -1+EPS)
      return 3;//ベクトル反対向きの側
    else if(segment.Length() < aimVec.Length())
      return 4;//ベクトル向きの側
    else
      return 5;//ベクトル上
  }

  public static long IsIntersect(Vector2 vecA, Vector2 vecB,
    Vector2 vecAsub, Vector2 vecBsub)//2線分の交差判定
  {
    bool answer = false;

    if(Vector2.WhereVector(vecA, vecB, vecAsub) + Vector2.WhereVector(vecA, vecB, vecBsub) == 3
    && Vector2.WhereVector(vecAsub, vecBsub, vecA) + Vector2.WhereVector(vecAsub, vecBsub, vecB) == 3)
      answer = true;
    if(Vector2.WhereVector(vecA, vecB, vecAsub) == 5 || Vector2.WhereVector(vecA, vecB, vecBsub) == 5
    || Vector2.WhereVector(vecAsub, vecBsub, vecA) == 5 || Vector2.WhereVector(vecAsub, vecBsub, vecB) == 5)
      answer = true;
    return((answer) ? 1 : 0);
  }

  public static Vector2 IntersectPoint(Vector2 vecA, Vector2 vecB, 
    Vector2 vecAsub, Vector2 vecBsub)//2線分の交点
  {
    Vector2 leftPoint = Vector2.Projection(vecA, vecB, vecAsub);//線分左端点の射影
    Vector2 rightPoint = Vector2.Projection(vecA, vecB, vecBsub);//線分右端点の射影
    decimal leftLength = (vecAsub - leftPoint).Length();
    decimal rightLength = (vecBsub - rightPoint).Length();

    leftLength = (decimal)(Math.Sqrt((double)leftLength));
    rightLength = (decimal)(Math.Sqrt((double)rightLength));
    
    if(leftLength < EPS) return leftPoint;
    else if(rightLength < EPS) return rightPoint;
    decimal ratio = leftLength / (leftLength + rightLength);
    return (leftPoint + ratio * (rightPoint - leftPoint));
  }

  public static Vector2[] circleLineIntersection(Vector2 centerPoint, decimal circleRadius, 
      Vector2 beginPoint, Vector2 endPoint)//円と直線の交点
    {
      Vector2[] answers = new Vector2[2];
      Vector2 segment = endPoint - beginPoint;
      Vector2 unitSegment = segment / (decimal)Math.Sqrt((double)segment.Length());
      Vector2 circleProjection = Projection(beginPoint, endPoint, centerPoint);//交点の中点
      decimal lineLength = 
        (decimal)Math.Sqrt((double)(circleRadius*circleRadius - (circleProjection-centerPoint).Length()));//端点と中点の距離
      //Console.WriteLine(unitSegment.x+" "+unitSegment.y);
      answers[0] = circleProjection + (unitSegment * lineLength);
      answers[1] = circleProjection - (unitSegment * lineLength);
      return answers;
    }

    public static Vector2[] CircleIntersection(Vector2 centerPointA, decimal circleRadiusA, 
        Vector2 centerPointB, decimal circleRadiusB)//2円の交点
      {
        Vector2[] answers = new Vector2[2];
        decimal centerDistance = Distance(centerPointA, centerPointB);//2円の中心間距離
        decimal centerAngle = Arg(centerPointB - centerPointA);
        decimal intersectionAngle = (decimal)Math.Acos((double)(circleRadiusA*circleRadiusA
          + centerDistance*centerDistance - circleRadiusB*circleRadiusB)
          /(double)(2*circleRadiusA*centerDistance));//余弦定理
        answers[0] = centerPointA + PoralCoordinate(circleRadiusA, centerAngle+intersectionAngle);
        answers[1] = centerPointA + PoralCoordinate(circleRadiusA, centerAngle-intersectionAngle); 
        if(answers[0].x > answers[1].x || (Math.Abs(answers[0].x - answers[1].x) < EPS && answers[0].y > answers[1].y))
        {
          Vector2 swapMemo = answers[0];
          answers[0] = answers[1];
          answers[1] = swapMemo;
        }
        return answers; 
      }

    public static decimal TriangleAria(Vector2 PointA, Vector2 PointB, Vector2 PointC)//3頂点に対する三角形の面積
    {
      decimal a = PointB.x - PointA.x;
      decimal b = PointB.y - PointA.y;
      decimal c = PointC.x - PointA.x;
      decimal d = PointC.y - PointA.y;
      return (Math.Abs(a*d-b*c)) / 2;
    }

    public static long PolygonPointContain(Vector2[] polygon, Vector2 aimPoint)
      //引数は多角形の頂点（反時計回りの順）と、点。返り値は多角形が点を含めば2,辺上は1,他は0
    {
      long n = polygon.Length;
      bool answer = false;
      for(int i = 0; i < n; i++)
      {
        if(WhereVector(polygon[i], polygon[(i+1)%n], aimPoint) == 5) return 1;//点は多角形上
        
        Vector2 toEgdeA = polygon[i] - aimPoint;//点から、多角形の各頂点へ線分を引く
        Vector2 toEgdeB = polygon[(i+1)%n] - aimPoint;
        if(toEgdeA.y > toEgdeB.y)
        {
          Vector2 swapMemo = toEgdeA;
          toEgdeA = toEgdeB;
          toEgdeB = swapMemo;
        }
        if(toEgdeA.y < EPS && toEgdeB.y > EPS && CrossProduct(toEgdeA, toEgdeB) > EPS)
        {//点をx軸正の方向に伸ばして、奇数回交われば内部。
          answer = !answer;
        }
      }
      return ((answer) ? 2 : 0);
    }

    public static decimal InscribedCircleRadius(Vector2 PointA, Vector2 PointB, Vector2 PointC)//三角形の内接円の半径
    {
      decimal triangleArea = TriangleAria(PointA, PointB, PointC);
      decimal length = Distance(PointA, PointB)+Distance(PointC, PointB)+Distance(PointA, PointC);
      decimal answer = triangleArea*2/length;
      return answer;
    }
    
}