using System; using System.Collections.Generic; using System.Linq; class Program { static string InputPattern = "InputX"; static List GetInputList() { var WillReturn = new List(); if (InputPattern == "Input1") { WillReturn.Add("3"); WillReturn.Add("1 0 4 1"); WillReturn.Add("2 4 15 4"); WillReturn.Add("0 0 1000000000000000000 1000000000000000000"); //3 //0 //1000000000000000000 } else { string wkStr; while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr); } return WillReturn; } static long[] GetSplitArr(string pStr) { return (pStr == "" ? new string[0] : pStr.Split(' ')).Select(pX => long.Parse(pX)).ToArray(); } // 2べき値[Y座標]なDict static Dictionary mBeki2Dict = new Dictionary(); static void Main() { List InputList = GetInputList(); mBeki2Dict[0] = 1; long Beki2 = 1; for (long I = 1; I < long.MaxValue; I++) { if (WillOverProd(Beki2, 2, long.MaxValue)) { mBeki2Dict[I] = long.MaxValue; break; } else { Beki2 *= 2; mBeki2Dict[I] = Beki2; } } long[] wkArr = { }; Action SplitAct = (pStr) => wkArr = GetSplitArr(pStr); foreach (string EachStr in InputList.Skip(1)) { SplitAct(EachStr); long SX = wkArr[0]; long SY = wkArr[1]; long TX = wkArr[2]; long TY = wkArr[3]; long Answer = Solve(SX, SY, TX, TY); Console.WriteLine(Answer); } } static long Solve(long pSX, long pSY, long pTX, long pTY) { // Y座標の移動コスト long BaseCost = Math.Abs(pSY - pTY); var AnswerList = new List(); long BaseY = Math.Max(pSY, pTY); for (long Y = BaseY; Y < long.MaxValue; Y++) { long YokoCost = DeriveCost(pSX, pTX, Y); AnswerList.Add(BaseCost + YokoCost + (Y - BaseY) * 2); if (YokoCost == 0) break; } return AnswerList.Min(); } // X座標2つと、Y座標を引数とし、コストを返す static long DeriveCost(long pX1, long pX2, long pY) { if (mBeki2Dict.ContainsKey(pY) == false) { return 0; } long Beki2 = mBeki2Dict[pY]; long Div1 = (pX1 / Beki2); long Div2 = (pX2 / Beki2); return Math.Abs(Div1 - Div2); } // long型の2正数の掛け算が、Limitを超えるかを返す static bool WillOverProd(long pA, long pB, long pLimit) { return pA > pLimit / pB; } }