Submission #3869241


Source Code Expand

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;
    }
    
}

Submission Info

Submission Time
Task B - Inscribed Bicycle
User suikameron
Language C# (Mono 4.6.2.0)
Score 500
Code Size 9705 Byte
Status AC
Exec Time 30 ms
Memory 11348 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 500 / 500
Status
AC × 2
AC × 18
Set Name Test Cases
Sample example0.txt, example1.txt
All 000.txt, 001.txt, 002.txt, 003.txt, 004.txt, 005.txt, 006.txt, 007.txt, 008.txt, 009.txt, 010.txt, 011.txt, 012.txt, 013.txt, 014.txt, 015.txt, example0.txt, example1.txt
Case Name Status Exec Time Memory
000.txt AC 30 ms 11348 KB
001.txt AC 29 ms 9300 KB
002.txt AC 28 ms 9300 KB
003.txt AC 28 ms 9300 KB
004.txt AC 30 ms 11348 KB
005.txt AC 29 ms 9300 KB
006.txt AC 29 ms 11348 KB
007.txt AC 29 ms 11348 KB
008.txt AC 29 ms 11348 KB
009.txt AC 28 ms 9300 KB
010.txt AC 29 ms 11348 KB
011.txt AC 29 ms 11348 KB
012.txt AC 28 ms 9300 KB
013.txt AC 29 ms 11348 KB
014.txt AC 29 ms 9300 KB
015.txt AC 29 ms 9300 KB
example0.txt AC 27 ms 9300 KB
example1.txt AC 28 ms 9300 KB