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

ABC181-C Collinearity


問題へのリンク


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("0 1");
            WillReturn.Add("0 2");
            WillReturn.Add("0 3");
            WillReturn.Add("1 1");
            //Yes
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("14");
            WillReturn.Add("5 5");
            WillReturn.Add("0 1");
            WillReturn.Add("2 5");
            WillReturn.Add("8 0");
            WillReturn.Add("2 1");
            WillReturn.Add("0 0");
            WillReturn.Add("3 6");
            WillReturn.Add("8 6");
            WillReturn.Add("5 9");
            WillReturn.Add("7 9");
            WillReturn.Add("3 4");
            WillReturn.Add("9 2");
            WillReturn.Add("9 8");
            WillReturn.Add("7 2");
            //No
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("9");
            WillReturn.Add("8 2");
            WillReturn.Add("2 3");
            WillReturn.Add("1 3");
            WillReturn.Add("3 7");
            WillReturn.Add("1 0");
            WillReturn.Add("8 8");
            WillReturn.Add("5 6");
            WillReturn.Add("9 7");
            WillReturn.Add("0 1");
            //Yes
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

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

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

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

        var PointList = new List<PointDef>();
        foreach (string EachStr in InputList.Skip(1)) {
            SplitAct(EachStr);

            PointDef WillAdd;
            WillAdd.X = wkArr[0];
            WillAdd.Y = wkArr[1];
            PointList.Add(WillAdd);
        }

        int UB = PointList.Count - 1;

        // 3つの座標の組合せを作る
        for (int I = 0; I <= UB; I++) {
            for (int J = I + 1; J <= UB; J++) {
                for (int K = J + 1; K <= UB; K++) {
                    PointDef Vector1 = SetVector(PointList[I], PointList[J]);
                    PointDef Vector2 = SetVector(PointList[I], PointList[K]);

                    if (IsLine(Vector1, Vector2)) {
                        Console.WriteLine("Yes");
                        return;
                    }
                }
            }
        }
        Console.WriteLine("No");
    }

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

    // ベクトル2つを引数として、1直線上に存在するかを返す
    static bool IsLine(PointDef pVector1, PointDef pVector2)
    {
        int Cross = DeriveCross(pVector1, pVector2);
        return Cross == 0;
    }

    // 外積を求める
    static int DeriveCross(PointDef pVector1, PointDef pVector2)
    {
        return pVector1.X * pVector2.Y - pVector1.Y * pVector2.X;
    }
}


解説

外積が0ならSinが0で、これは0度か180度なので
2つのベクトルは1直線上に存在します。