Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Cross Points of a Circe and a Line

For given a circle $c$ and a line $l$, print the coordinates of the cross points of them.

Input

The input is given in the following format.

$cx\; cy\; r$

$q$

$Line_1$

$Line_2$

:

$Line_q$

In the first line, the center coordinate of the circle and its radius are given by $cx$, $cy$ and $r$. In the second line, the number of queries $q$ is given.

In the following $q$ lines, as queries, $Line_i$ are given ($1 \leq i \leq q$) in the following format.

$x_1\; y_1\; x_2\; y_2$

Each line is represented by two points $p1$ and $p2$ which the line crosses. The coordinate of $p1$ and $p2$ are given by ($x1$, $y1$) and ($x2$, $y2$) respectively. All input values are given in integers.

Output

For each query, print the coordinates of the cross points in the following rules.

If there is one cross point, print two coordinates with the same values.

Print the coordinate with smaller $x$ first. In case of a tie, print the coordinate with smaller $y$ first.

The output values should be in a decimal fraction with an error less than 0.000001.

Constraints

$p1$ and $p2$ are different

The circle and line have at least one cross point

$1 \leq q \leq 1,000$

$-10,000 \leq cx, cy, x1, y1, x2, y2 \leq 10,000$

$1 \leq r \leq 10,000$

Sample Input and Output

Sample Input

2 1 1
2
0 1 4 1
3 0 3 3

Sample Output

1.00000000 1.00000000 3.00000000 1.00000000
3.00000000 1.00000000 3.00000000 1.00000000

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;//リストの使用
using System.Collections.Generic;
class Program
{
static decimal EPS = 1e-10m;//小数誤差比較
	static void Main()
	{
		string[] input = Console.ReadLine().Split(' ');
    Vector2 centerPoint = new Vector2(decimal.Parse(input[0]), decimal.Parse(input[1]));
    decimal circleRadius = decimal.Parse(input[2]);
		long q = long.Parse(Console.ReadLine());

    for(long i = 0; i < q; i++)
    {
      string[] inputSub = Console.ReadLine().Split(' ');
      Vector2 beginPoint = new Vector2(decimal.Parse(inputSub[0]), decimal.Parse(inputSub[1]));
      Vector2 endPoint = new Vector2(decimal.Parse(inputSub[2]), decimal.Parse(inputSub[3]));
      Vector2[] answers = Vector2.circleLineIntersection(centerPoint, circleRadius, beginPoint, endPoint);//円と直線の交点
      Vector2 swapMemo;
      if(answers[0].x>answers[1].x || (Math.Abs(answers[0].x-answers[1].x)<EPS && answers[0].y>answers[1].y))
      {
        swapMemo = answers[0];
        answers[0] = answers[1];
        answers[1] = swapMemo;
      }
      Console.WriteLine(answers[0].x + " " + answers[0].y + " " + answers[1].x + " " + answers[1].y);
    }
	}
}

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