AtCoderのABC    次のABCの問題へ    前のABCの問題へ

ABC197-D Opposite


問題へのリンク


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");
            WillReturn.Add("1 1");
            WillReturn.Add("2 2");
            //2.00000000000 1.00000000000
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("6");
            WillReturn.Add("5 3");
            WillReturn.Add("7 4");
            //5.93301270189 2.38397459622
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

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

        double N = double.Parse(InputList[0]);

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

        SplitAct(InputList[1]);
        double X0 = wkArr[0];
        double Y0 = wkArr[1];

        SplitAct(InputList[2]);
        double XN2 = wkArr[0];
        double YN2 = wkArr[1];

        // 中点を求める
        double MidX = (X0 + XN2) / 2;
        double MidY = (Y0 + YN2) / 2;

        // 角度を求める
        double Rad = 2 * Math.PI / N;

        PointDef C1_Pos = new PointDef() { X = MidX, Y = MidY };
        PointDef C2_Pos = new PointDef() { X = X0, Y = Y0 };

        PointDef BaseVector = SetVector(C1_Pos, C2_Pos);

        PointDef KaitenVector = Exec1JiHenkan(BaseVector, Math.Sin(Rad), Math.Cos(Rad));

        double AnswerX = MidX + KaitenVector.X;
        double AnswerY = MidY + KaitenVector.Y;
        Console.WriteLine("{0} {1}", AnswerX, AnswerY);
    }

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

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

    // ベクトルとSinとCosを引数として、回転したベクトルを返す
    static PointDef Exec1JiHenkan(PointDef pPos, double pSin, double pCos)
    {
        PointDef WillReturn;
        WillReturn.X = pCos * pPos.X + pPos.Y * -pSin;
        WillReturn.Y = pSin * pPos.X + pPos.Y * pCos;
        return WillReturn;
    }
}


解説

最初に中点を求めます。

360/Nで回転移動の角度が分かるので
1次変換でベクトルの回転移動を行ってます。