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