コード例 #1
0
        private SkyLine FindSkyline(Building[] building, int low, int high)
        {
            //here when we divide and seperate recursion there are two possibilities
            //low will be equal to high

            //if we handle low = high, low won't be greater to high and high won't go lesser than low

            if (low == high)
            {
                //You have one building, get skylines from the building
                //eg (1,11,5) will give (1,11) and (5,0)
                // update 06/28/2017
                // A skyline is a collection of rectangular strips.
                // A rectangular strip is represented as a pair (left, ht) where left is x coordinate of left side of strip and ht is height of strip
                // here (5, 0) because 5 is the x corordinate of the left side of the strip (2nd strip) of height 0. ..
                SkyLine result = new SkyLine(2);
                result.append(new Strip(building[low].left, building[low].height));
                result.append(new Strip(building[low].right, 0));
                return(result);
            }
            //default case low will be lesser than high

            int middle = (low + high) / 2;

            SkyLine skyline1 = FindSkyline(building, low, middle);
            SkyLine skyline2 = FindSkyline(building, middle + 1, high);

            //order is important here merge skyline1 to skyline2
            return(MergeTwoSkylines(skyline1, skyline2));
        }
コード例 #2
0
        //Note: order is important. This function append the skyline2 to skyline1
        //same as calling skyline1.merge(skyline2)
        public SkyLine MergeTwoSkylines(SkyLine skyline1, SkyLine skyline2)
        {
            // Create a resultant skyline with capacity as sum of two
            // skylines
            SkyLine result = new SkyLine(skyline1.GetSize() + skyline2.GetSize());

            // The idea is similar to merge of merge sort, start from first strips of two skylines, compare x coordinates.
            //Pick the strip with smaller x coordinate and add it to result.
            //The height of added strip is considered as maximum of current heights from skyline1 and skyline2.
            //Example to show working of merge:

            //  Height of new Strip is always obtained by takin maximum of following
            //     (a) Current height from skyline1, say 'h1'.
            //     (b) Current height from skyline2, say 'h2'
            //  h1 and h2 are initialized as 0. h1 is updated when a strip from
            //  SkyLine1 is added to result and h2 is updated when a strip from
            //  SkyLine2 is added.

            int h1 = 0, h2 = 0;

            int leftpointer  = 0; //left half pointer
            int rightpointer = 0; //right half pointer

            while (leftpointer < skyline1.GetSize() && rightpointer < skyline2.GetSize())
            {
                int mergeheight = 0;

                if (skyline1.strips[leftpointer].left < skyline2.strips[rightpointer].left)
                {
                    h1          = skyline1.strips[leftpointer].height;
                    mergeheight = Math.Max(h1, h2);
                    result.append(new Strip(skyline1.strips[leftpointer].left, mergeheight));
                    leftpointer++;
                }
                else
                {
                    //don't worry about equal condition. result.append already has logic to skip skyline if the previous skyline has same height and left
                    h2          = skyline2.strips[rightpointer].height;
                    mergeheight = Math.Max(h1, h2);
                    result.append(new Strip(skyline2.strips[rightpointer].left, mergeheight));
                    rightpointer++;
                }
            }

            // If there are strips left in this skyline or other
            // skyline
            while (leftpointer < skyline1.GetSize())
            {
                result.append(skyline1.strips[leftpointer]);
                leftpointer++;
            }
            while (rightpointer < skyline2.GetSize())
            {
                result.append(skyline2.strips[rightpointer]);
                rightpointer++;
            }

            return(result);
        }
コード例 #3
0
        private SkyLine GetSkylinesFromSingleBuilding(Building building)
        {
            //there are two strips for single building
            SkyLine result = new SkyLine(2);

            result.append(new Strip(building.left, building.height));
            result.append(new Strip(building.right, 0));
            return(result);
        }
コード例 #4
0
        private void button1_Click(object sender, EventArgs e)
        {
            // Input: Array of buildings
            //{ (1,11,5), (2,6,7), (3,13,9), (12,7,16), (14,3,25),
            //  (19,18,22), (23,13,29), (24,4,28) }

            List <Building> buildings = new List <Building>();
            Building        building1 = new Building(1, 11, 5);
            Building        building2 = new Building(2, 6, 7);
            Building        building3 = new Building(3, 13, 9);
            Building        building4 = new Building(12, 7, 16);
            Building        building5 = new Building(14, 3, 25);
            Building        building6 = new Building(19, 18, 22);
            Building        building7 = new Building(23, 13, 29);
            Building        building8 = new Building(24, 4, 28);

            buildings.Add(building1);
            buildings.Add(building2);
            //buildings.Add(building3);
            //buildings.Add(building4);
            //buildings.Add(building5);
            //buildings.Add(building6);
            //buildings.Add(building7);
            //buildings.Add(building8);

            SkyLine result = FindSkyline(buildings.ToArray(), 0, buildings.Count - 1);

            StringBuilder sb = new StringBuilder();

            foreach (Strip s in result.strips)
            {
                if (s != null)
                {
                    sb.Append("(").Append(s.left).Append(",").Append(s.height).Append(")");
                }
            }

            string output = sb.ToString();

            //           Skyline for given buildings is
            //(1, 11),  (3, 13),  (9, 0),  (12, 7),  (16, 3),  (19, 18),
            //(22, 3),  (23, 13),  (29, 0),
        }
コード例 #5
0
        private SkyLine GetSkyline(List <Building> buildings)
        {
            SkyLine result = null;

            foreach (Building building in buildings)
            {
                SkyLine skyline = GetSkylinesFromSingleBuilding(building);

                if (result == null)
                {
                    result = skyline;
                }
                else
                {
                    result = MergeTwoSkylines(result, skyline);
                }
            }

            return(result);
        }