예제 #1
0
파일: QTree.cs 프로젝트: xoposhiy/icfpc2012
        public static QTree Set(QTree root, int x, int y, int leftX, int rightX, int leftY, int rightY, MapCell mapCell)
        {
            QTree newRoot = new QTree();
            if (leftX == rightX && leftY == rightY)
            {
                newRoot.data = mapCell;
                return newRoot;
            }
            int middleX = (leftX + rightX) / 2;
            int middleY = (leftY + rightY) / 2;
            int childId = (x > middleX ? 1 : 0);
            if (y > middleY) childId |= 2;
            newRoot.children = new QTree[4];
            for (int i = 0; i < 4; ++i)
                newRoot.children[i] = root.children[i];

            if (y <= middleY)
            {
                if (x <= middleX)
                    newRoot.children[childId] = Set(root.children[childId], x, y, leftX, middleX, leftY, middleY, mapCell);
                else
                    newRoot.children[childId] = Set(root.children[childId], x, y, middleX + 1, rightX, leftY, middleY, mapCell);
            }
            else
            {
                if (x <= middleX)
                    newRoot.children[childId] = Set(root.children[childId], x, y, leftX, middleX, middleY + 1, rightY, mapCell);
                else
                    newRoot.children[childId] = Set(root.children[childId], x, y, middleX + 1, rightX, middleY + 1, rightY, mapCell);
            }
            return newRoot;
        }
예제 #2
0
파일: QTree.cs 프로젝트: xoposhiy/icfpc2012
 public static MapCell Get(QTree root, int x, int y, int leftX, int rightX, int leftY, int rightY)
 {
     if (leftX == rightX && leftY == rightY)
         return root.data;
     int middleX = (leftX + rightX) / 2;
     int middleY = (leftY + rightY) / 2;
     int childId = (x > middleX ? 1 : 0);
     if (y > middleY) childId |= 2;
     if (y <= middleY)
     {
         if (x <= middleX)
             return Get(root.children[childId], x, y, leftX, middleX, leftY, middleY);
         return Get(root.children[childId], x, y, middleX + 1, rightX, leftY, middleY);
     }
     if (x <= middleX)
         return Get(root.children[childId], x, y, leftX, middleX, middleY + 1, rightY);
     return Get(root.children[childId], x, y, middleX + 1, rightX, middleY + 1, rightY);
 }
예제 #3
0
파일: QTree.cs 프로젝트: xoposhiy/icfpc2012
        public static QTree SetPack(QTree root, List<Pack> listData, int listLeft, int listRight, int leftX, int rightX, int leftY, int rightY)
        {
            QTree newRoot = new QTree();
            if (leftX == rightX && leftY == rightY)
            {
                newRoot.data = listData[listLeft].data;
                return newRoot;
            }
            newRoot.children = new QTree[4];
            int ptr = listLeft;
            int from = listLeft;
            int middleX = (leftX + rightX) / 2;
            int middleY = (leftY + rightY) / 2;
            int[] leftLimitX = new[] {leftX, middleX + 1};
            int[] rightLimitsX = new[] {middleX, rightX};
            int[] leftLimitY = new[] {leftY, middleY + 1};
            int[] rightLimitsY = new[] {middleY, rightY};

            for (int i = 0; i < 3; ++i)
            {
                for (int j = from; j <= listRight; ++j)
                    if (listData[j].x >= leftLimitX[i&1] && listData[j].x <= rightLimitsX[i&1])
                        if (listData[j].y >= leftLimitY[(i&2)>>1] && listData[j].y <= rightLimitsY[(i&2) >> 1])
                        {
                            var temp = listData[j];
                            listData[j] = listData[ptr];
                            listData[ptr] = temp;
                            ++ptr;
                        }
                if (ptr > from)
                    newRoot.children[i] = SetPack(root.children[i], listData, from, ptr - 1, leftLimitX[i & 1], rightLimitsX[i & 1], leftLimitY[(i & 2) >> 1], rightLimitsY[(i & 2) >> 1]);
                else
                    newRoot.children[i] = root.children[i];
                from = ptr;
            }
            if (from <= listRight)
                newRoot.children[3] = SetPack(root.children[3], listData, from, listRight, leftLimitX[1], rightLimitsX[1], leftLimitY[1], rightLimitsY[1]);
            else
                newRoot.children[3] = root.children[3];

            return newRoot;
        }
예제 #4
0
파일: Map.cs 프로젝트: xoposhiy/icfpc2012
        public Map(string[] lines)
        {
            State = CheckResult.Nothing;

            var firstBlankLineIndex = Array.IndexOf(lines, "");
            Height = firstBlankLineIndex == -1 ? lines.Length : firstBlankLineIndex;
            Width = lines.Take(Height).Max(a => a.Length);

            field = new QTree();
            for (var row = 0; row < Height + 2; row++)
                for (var col = 0; col < Width + 2; col++)
                {
                    if (row == 0 || row == Height + 1 || col == 0 || col == Width + 1)
                        QTree.SimpleAdd(field, col, row, 0, Width + 1, 0, Height + 1, MapCell.Wall);
                    else
                    {
                        var x = col - 1;
                        var y = Height - row;
                        var line = lines[y].PadRight(Width, ' ');
                        var mapCell = Parse(line[x]);
                        QTree.SimpleAdd(field, col, row, 0, Width + 1, 0, Height + 1, mapCell);
                        if (mapCell == MapCell.Lambda || mapCell == MapCell.LambdaRock)
                            TotalLambdaCount++;
                        else if (mapCell == MapCell.Robot)
                        {
                            RobotX = col;
                            RobotY = row;
                        }
                        else if (mapCell == MapCell.ClosedLift || mapCell == MapCell.OpenedLift)
                            Lift = new Vector(col, row);
                        else if (mapCell == MapCell.Beard)
                            Beard.Add(new Vector(col, row));
                        else if (TargetsChars.Contains((char) mapCell))
                            Targets[mapCell] = new Vector(col, row);
                        else if (TrampolinesChars.Contains((char) mapCell))
                            Trampolines[mapCell] = new Vector(col, row);
                    }
                }

            InitializeVariables(lines.Skip(Height + 1).ToArray());

            Height += 2;
            Width += 2;

            InitializeActiveRocks();
        }
예제 #5
0
파일: QTree.cs 프로젝트: xoposhiy/icfpc2012
        public void PackTest()
        {
            var t = new QTree();
            List<Pack> list = new List<Pack>();
            var t2 = new QTree();

            for (var i = 0; i < 501; ++i)
                for (var j = 0; j < 501; ++j)
                {
                    QTree.SimpleAdd(t, i, j, 0, 500, 0, 500, MapCell.Earth);
                    QTree.SimpleAdd(t2, i, j, 0, 500, 0, 500, MapCell.Earth);
                }
            int x = 400, y = 400;
            List <MapCell> cells = new List<MapCell> {MapCell.Earth, MapCell.OpenedLift, MapCell.Lambda, MapCell.Trampoline3, MapCell.Wall };
            for (int i = 0; i < 500; ++i)
            {
                list.Add(new Pack {data = cells[i%5], x = x, y = y});
                --x;
                if (x == 0)
                {
                    x = 400;
                    --y;
                }
            }
            foreach (var item in list)
                QTree.Set(t2, item.x, item.y, 0, 500, 0, 500, item.data);
            QTree.SetPack(t, list, 0, list.Count - 1, 0, 500, 0, 500);
            foreach (var item in list)
                Assert.AreEqual(QTree.Get(t2, item.x, item.y, 0, 500, 0, 500), QTree.Get(t2, item.x, item.y, 0, 500, 0, 500));
        }
예제 #6
0
파일: QTree.cs 프로젝트: xoposhiy/icfpc2012
 public void Init()
 {
     var t = new QTree();
     for (var x = 0; x < 3; x++)
         for (var y = 0; y < 10; ++y)
             switch (x + y%4)
             {
                 case 0:
                     QTree.SimpleAdd(t, x, y, 0, 2, 0, 9, MapCell.Earth);
                     break;
                 case 1:
                     QTree.SimpleAdd(t, x, y, 0, 2, 0, 9, MapCell.Robot);
                     break;
                 case 2:
                     QTree.SimpleAdd(t, x, y, 0, 2, 0, 9, MapCell.Lambda);
                     break;
                 case 3:
                     QTree.SimpleAdd(t, x, y, 0, 2, 0, 9, MapCell.ClosedLift);
                     break;
             }
     for (var x = 0; x < 3; x++)
         for (var y = 0; y < 10; ++y)
             switch (x + y%4)
             {
                 case 0:
                     Assert.AreEqual(QTree.Get(t, x, y, 0, 2, 0, 9), MapCell.Earth);
                     break;
                 case 1:
                     Assert.AreEqual(QTree.Get(t, x, y, 0, 2, 0, 9), MapCell.Robot);
                     break;
                 case 2:
                     Assert.AreEqual(QTree.Get(t, x, y, 0, 2, 0, 9), MapCell.Lambda);
                     break;
                 case 3:
                     Assert.AreEqual(QTree.Get(t, x, y, 0, 2, 0, 9), MapCell.ClosedLift);
                     break;
             }
 }
예제 #7
0
파일: QTree.cs 프로젝트: xoposhiy/icfpc2012
 public static void SimpleAdd(QTree root, int x, int y, int leftX, int rightX, int leftY, int rightY, MapCell mapCell)
 {
     if (leftX == rightX && leftY == rightY)
     {
         root.data = mapCell;
         return;
     }
     if (root.children == null)
         root.children = new QTree[4];
     int middleX = (leftX + rightX)/2;
     int middleY = (leftY + rightY)/2;
     int childId = (x > middleX ? 1 : 0);
     if (y > middleY) childId |= 2;
     if (root.children[childId] == null)
         root.children[childId] = new QTree();
     if (y <= middleY)
     {
         if (x <= middleX)
             SimpleAdd(root.children[childId], x, y, leftX, middleX, leftY, middleY, mapCell);
         else
             SimpleAdd(root.children[childId], x, y, middleX + 1, rightX, leftY, middleY, mapCell);
     }
     else
     {
         if (x <= middleX)
             SimpleAdd(root.children[childId], x, y, leftX, middleX, middleY + 1, rightY, mapCell);
         else
             SimpleAdd(root.children[childId], x, y, middleX + 1, rightX, middleY + 1, rightY, mapCell);
     }
 }