E8本(数学)
次のE8本(数学)の問題へ
前のE8本(数学)の問題へ
E8本(数学) 077 Distance Sum
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("2");
WillReturn.Add("1 2");
WillReturn.Add("10 20");
//27
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct PointDef
{
internal long X;
internal long Y;
}
static long UB;
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => long.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);
}
UB = PointList.Count - 1;
long[] XArr = PointList.Select(pX => pX.X).ToArray();
long[] YArr = PointList.Select(pX => pX.Y).ToArray();
long SumX = DeriveSum(XArr);
long SumY = DeriveSum(YArr);
Console.WriteLine(SumX + SumY);
}
static long DeriveSum(long[] pArr)
{
long Sum = 0;
Array.Sort(pArr);
long LeftCnt = 1;
long RightCnt = pArr.Length - 1;
for (long I = 0; I <= UB - 1; I++) {
long PairInd = I + 1;
Sum += (pArr[PairInd] - pArr[I]) * LeftCnt * RightCnt;
LeftCnt++;
RightCnt--;
}
return Sum;
}
}
解説
全ての点の組み合わせのマンハッタン距離の総和なので
X成分とY成分を独立して考えます。
X成分だけで
1 2 3 4 5
という5つの座標で考察すると
線分12を使う点のペアは、積の法則で1*4で4通り
線分23を使う点のペアは、積の法則で2*3で6通り
線分34を使う点のペアは、積の法則で3*2で6通り
線分45を使う点のペアは、積の法則で4*1で4通り
といった方法で求めることができます。