E8本(数学)    次のE8本(数学)の問題へ    前のE8本(数学)の問題へ

E8本(数学) 035 Two Circles


問題へのリンク


C#のソース

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static string InputPattern = "InputX";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("4 1 2");
            WillReturn.Add("1 5 3");
            //4
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("1 1 6");
            WillReturn.Add("3 3 2");
            //1
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("6 6 6");
            WillReturn.Add("6 6 6");
            //2
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    struct PointDef
    {
        internal long X;
        internal long Y;
    }

    struct CircleInfoDef
    {
        internal long X;
        internal long Y;
        internal long R;
    }
    static List<CircleInfoDef> mCircleInfoList = new List<CircleInfoDef>();

    static void Main()
    {
        List<string> InputList = GetInputList();

        long[] wkArr = { };
        Action<string> SplitAct = pStr =>
            wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();

        foreach (string EachStr in InputList) {
            SplitAct(EachStr);
            CircleInfoDef WillAdd;
            WillAdd.X = wkArr[0];
            WillAdd.Y = wkArr[1];
            WillAdd.R = wkArr[2];
            mCircleInfoList.Add(WillAdd);
        }

        int Result = CheckTwoCircle(mCircleInfoList[0], mCircleInfoList[1]);
        Console.WriteLine(Result);
    }

    // 円と円の位置関係を判定する
    // 判定1 一方の円が他方の円を完全に含み、2つの円は接していない
    // 判定2 一方の円が他方の円を完全に含み、2つの円は接している
    // 判定3 2つの円が互いに交差する
    // 判定4 2つの円の内部に共通部分は存在しないが、2つの円は接している
    // 判定5 2つの円の内部に共通部分は存在せず、2つの円は接していない
    static int CheckTwoCircle(CircleInfoDef pCircleInfo1, CircleInfoDef pCircleInfo2)
    {
        PointDef DiffVect = SetVector(pCircleInfo1.X, pCircleInfo1.Y,
                                      pCircleInfo2.X, pCircleInfo2.Y);
        long DiffVectNorm = DeriveNorm(DiffVect);

        long RDiff = pCircleInfo1.R - pCircleInfo2.R;
        long RDiffNorm = RDiff * RDiff;

        long RSum = pCircleInfo1.R + pCircleInfo2.R;
        long RSumNorm = RSum * RSum;

        // 判定1
        if (DiffVectNorm < RDiffNorm) {
            return 1;
        }

        // 判定2
        if (DiffVectNorm == RDiffNorm) {
            return 2;
        }

        // 判定3
        if (RDiffNorm < DiffVectNorm && DiffVectNorm < RSumNorm) {
            return 3;
        }

        // 判定4
        if (RSumNorm == DiffVectNorm) {
            return 4;
        }

        // 判定5
        return 5;
    }

    // 始点と終点の座標を引数として、始点から終点へのベクトルを返す
    static PointDef SetVector(long pStaX, long pStaY, long pEndX, long pEndY)
    {
        PointDef WillReturn;
        WillReturn.X = pEndX - pStaX;
        WillReturn.Y = pEndY - pStaY;
        return WillReturn;
    }

    // ベクトルのNormを求める
    static long DeriveNorm(PointDef pVector)
    {
        return pVector.X * pVector.X + pVector.Y * pVector.Y;
    }
}


解説

数直線上の二つの円の中心を移動させて考えると
半径と、中心間の距離から条件を導くことができます。