public int solution(int[] X, int[] Y) { var N = X.Length; var map = new int[N, N]; var arrX = new Point[N]; var arrY = new Point[N]; Point.Load(arrX, X, Y); for (var i = 0; i < N; i++) { arrY[i] = arrX[i]; } var xcomp = new XComp(); var ycomp = new YComp(); Array.Sort(arrX, xcomp); Array.Sort(arrY, ycomp); for (var i = 0; i < N; ) { var istart = i; for (; i < N && arrX[i].X == arrX[istart].X; i++) { var pi = arrX[i]; var parityi = pi.Y % 2; for (var j = i + 1; j < N && arrX[j].X == arrX[i].X; j++) { if (arrX[j].Y % 2 == parityi) { var x = pi.X; var y = (pi.Y + arrX[j].Y) / 2; map[x, y]++; } } } } var total = 0; for (var i = 0; i < N; ) { var istart = i; for (; i < N && arrY[i].Y == arrY[istart].Y; i++) { var pi = arrY[i]; var paritxi = pi.X % 2; for (var j = i + 1; j < N && arrY[j].Y == arrY[i].Y; j++) { if (arrY[j].X%2==paritxi) { var x = (pi.X + arrY[j].X) / 2; var y = pi.Y; if (map[x, y] > 0) { total += map[x, y]; } } } } } return total; }
public int solution(int[] X, int[] Y) { var xcomp = new XComp(); var ycomp = new YComp(); var N = X.Length; var arrX = new Point[N]; var arrY = new Point[N]; Point.Load(arrX, X, Y); for (var i = 0; i < N; i++) { arrY[i] = arrX[i]; } Array.Sort(arrX, xcomp); Array.Sort(arrY, ycomp); #if LINEARITY_CHECK for (var i = 0; i < N; i++) { arrX[i].IX = i; arrY[i].IY = i; } #endif var midsX = new Point[N * N / 2]; var midsY = new Point[N * N / 2]; var px = 0; var py = 0; var llx = new LinkedList<Tuple<int, int>>(); var lly = new LinkedList<Tuple<int, int>>(); for (var i = 0; i < arrX.Length - 1; #if FIBB_FIND_END i++ #endif ) { #if FIBB_FIND_END var pi = arrX[i]; var jend = i; FibbInc(ref jend, t => t < arrX.Length && arrX[t].X == pi.X); #if BOUNARY_EXCLUSION if (arrX[i].X == arrX[0].X) { i = jend - 1; continue; } if (arrX[i].X == arrX[arrX.Length - 1].X) { break; } #endif if (jend > i+1) { var pbegin = py; for (; i < jend-1; i++) { pi = arrX[i]; var parityi = pi.Y % 2; for (var j = i + 1; j < jend; j++) { if (arrX[j].Y % 2 == parityi #if LINEARITY_CHECK && !IsLinear(arrX[j], arrX[i]) #endif ) { midsY[py++] = new Point { X = pi.X, Y = (pi.Y + arrX[j].Y) / 2 }; } } } if (py > pbegin + 1) { lly.AddLast(new Tuple<int, int>(pbegin, py - pbegin)); } } #else var istart = i; var pbegin = py; for (; i < arrX.Length && arrX[i].X == arrX[istart].X; i++) { var pi = arrX[i]; var parityi = pi.Y % 2; for (var j = i + 1; j < arrX.Length && arrX[j].X == arrX[i].X; j++) { if (parityi == arrX[j].Y % 2) { midsY[py++] = new Point { X = pi.X, Y = (pi.Y + arrX[j].Y) / 2 }; } } } if (py > pbegin + 1) { lly.AddLast(new Tuple<int, int>(pbegin, py - pbegin)); } #endif } for (var i = 0; i < arrY.Length - 1; #if FIBB_FIND_END i++ #endif ) { #if FIBB_FIND_END var pi = arrY[i]; var jend = i; FibbInc(ref jend, t => t < arrY.Length && arrY[t].Y == pi.Y); #if BOUNARY_EXCLUSION if (arrY[i].Y == arrY[0].Y) { i = jend - 1; continue; } if (arrY[i].Y == arrY[arrY.Length - 1].Y) { break; } #endif if (jend > i + 1) { var pbegin = px; for (; i < jend - 1; i++) { pi = arrY[i]; var parityi = pi.X % 2; for (var j = i + 1; j < jend; j++) { if (arrY[j].X % 2 == parityi #if LINEARITY_CHECK && !IsLinear(arrY[j], arrY[i]) #endif ) { midsX[px++] = new Point { X = (pi.X + arrY[j].X) / 2, Y = pi.Y }; } } } if (px > pbegin + 1) { llx.AddLast(new Tuple<int, int>(pbegin, px - pbegin)); } } #else var istart = i; var pbegin = px; for (; i < arrY.Length && arrY[i].Y == arrY[istart].Y; i++) { var pi = arrY[i]; var parityi = pi.X % 2; for (var j = i + 1; j < arrY.Length && arrY[j].Y == arrY[i].Y; j++) { if (arrY[j].X % 2 == parityi) { midsX[px++] = new Point { X = (pi.X + arrY[j].X) / 2, Y = pi.Y }; } } } if (px > pbegin + 1) { llx.AddLast(new Tuple<int, int>(pbegin, px - pbegin)); } #endif } IComparer<Point> sel; if (px < py) { sel = xcomp; Array.Sort(midsX, 0, px, xcomp); foreach (var t in lly) { Array.Sort(midsY, t.Item1, t.Item2, ycomp); } } else { sel = ycomp; Array.Sort(midsY, 0, py, ycomp); foreach(var t in llx) { Array.Sort(midsX, t.Item1, t.Item2, xcomp); } } var total = 0; for (int i = 0, j = 0; i < px && j < py;) { var mx = midsX[i]; var my = midsY[j]; var c = sel.Compare(mx, my); if (c == 0) { var oldi = i; var oldj = j; FibbInc(ref i, t => t < px && sel.Compare(midsX[t], mx) == 0); FibbInc(ref j, t => t < py && sel.Compare(midsY[t], my) == 0); total += (i - oldi) * (j - oldj); } else if (c < 0) { FibbInc(ref i, t => t < px && sel.Compare(midsX[t], my) < 0); } else { FibbInc(ref j, t => t < py && sel.Compare(mx, midsY[t]) > 0); } } return total; }