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直線上に存在します。