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

直交判定

平面上の異なる 4 点、$A (x_A, y_A)$, $B (x_B, y_B)$, $C (x_C, y_C)$, $D (x_D, y_D)$ の座標を読み込んで、直線 $AB$ と $CD$ が直交する場合には YES、直交しない場合には NO と出力するプログラムを作成してください。ここで、「直線」とは線分のことではありません。以下の図を参考にして下さい。

Input

複数のデータセットが与えられます。各データセットの形式は以下のとおりです。

$x_A$ $y_A$ $x_B$ $y_B$ $x_C$ $y_C$ $x_D$ $y_D$

$x_A$, $y_A$, $x_B$, $y_B$, $x_C$, $y_C$, $x_D$, $y_D$ はそれぞれ -100 以上 100 以下であり、各値は小数点以下最大 5 桁までの数字を含む実数で与えられます。

データセットの数は 100 を超えません。

Output

各データセットに対して、YES または NO を１行に出力して下さい。

Sample Input

1.0 1.0 2.0 2.0 0.0 0.0 1.0 -1.0
0.0 0.0 2.0 0.0 -1.0 2.0 2.0 2.0
10.0 6.0 3.4 5.2 6.8 9.5 4.3 2.1
2.5 3.5 2.5 4.5 -3.3 -2.3 6.8 -2.3

Output for the Sample Input

YES
NO
NO
YES

Solution in C# (judge verdict: Accepted)

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

namespace AOJ0058
{
    class Program
    {
        private const double Epsilon = 0.00000001;

        static void Main()
        {
            foreach(var data in ReadInputs())
            {
                var pA = new Point(data[0], data[1]);
                var pB = new Point(data[2], data[3]);
                var pC = new Point(data[4], data[5]);
                var pD = new Point(data[6], data[7]);
                // ReSharper disable InconsistentNaming
                var vAB = new Vector(pA, pB);
                var vCD = new Vector(pC, pD);
                // ReSharper restore InconsistentNaming
                Console.WriteLine(Math.Abs(vAB * vCD) < Epsilon ? "YES" : "NO");
            }
        }

        public static IEnumerable<double[]> ReadInputs()
        {
            string line;
            while ((line = Console.ReadLine()) != null)
            {
                yield return line.Split(' ').Select(double.Parse).ToArray();
            }
        }
    }

    public class Point
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double Z { get; set; }

        public Point(double x = 0, double y = 0, double z = 0)
        {
            X = x;
            Y = y;
            Z = z;
        }
    }

    public class Vector
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double Z { get; set; }

        public Vector(double x = 0, double y = 0, double z = 0)
        {
            X = x;
            Y = y;
            Z = z;
        }

        public Vector(Point p1, Point p2)
            : this(p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z)
        {
        }

        public Vector Cross(Vector other)
        {
            var x = Y * other.Z - Z * other.Y;
            var y = Z * other.X - X * other.Z;
            var z = X * other.Y - Y * other.X;

            return new Vector(x, y, z);
        }

        public static double operator *(Vector v1, Vector v2)
        {
            return v1.X*v2.X + v1.Y*v2.Y + v1.Z*v2.Z;
        }

        public static Vector operator *(Vector v, double a)
        {
            return new Vector(a*v.X, a*v.Y, a*v.Z);
        }

        public static Vector operator *(double a, Vector v)
        {
            return v*a;
        }
    }
}