100天际线问题(218)

作者: Turbo时间限制: 1S章节: 线段树

晚于: 2020-09-09 12:00:00后提交分数乘系数50%

问题描述 :

城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。现在,假设您获得了城市风光照片(图A)上显示的所有建筑物的位置和高度,请编写一个程序以输出由这些建筑物形成的天际线(图B)。

Buildings Skyline Contour

 

每个建筑物的几何信息用三元组 [Li,Ri,Hi] 表示,其中 Li 和 Ri 分别是第 i 座建筑物左右边缘的 x 坐标,Hi 是其高度。可以保证 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX 和 Ri - Li > 0。您可以假设所有建筑物都是在绝对平坦且高度为 0 的表面上的完美矩形。

 

例如,图A中所有建筑物的尺寸记录为:[ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] 。

 

输出是以 [ [x1,y1], [x2, y2], [x3, y3], ... ] 格式的“关键点”(图B中的红点)的列表,它们唯一地定义了天际线。关键点是水平线段的左端点。请注意,最右侧建筑物的最后一个关键点仅用于标记天际线的终点,并始终为零高度。此外,任何两个相邻建筑物之间的地面都应被视为天际线轮廓的一部分。

 

例如,图B中的天际线应该表示为:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ]。

 

输入说明 :

首先输入建筑物的数量n

然后输入n行,每行是一座建筑物的几何信息三元组 [Li,Ri,Hi]

n在 [0, 10000] 范围内

建筑物列表按照Li 的x 坐标进行升序排列输入

 

输出说明 :

输出天际线表示,每个关键点一行,每行两个整数。

输出列表必须按关键点的 x 坐标升序排列输出。

输出天际线中不得有连续的相同高度的水平线。例如 [...[2 3], [4 5], [7 5], [11 5], [12 7]...] 是不正确的答案;三条高度为 5 的线应该在最终输出中合并为一个:[...[2 3], [4 5], [12 7], ...]

 

输入范例 :

输出范例 :

#include <iostream>
#include <vector>
#include <set>
using namespace std;
class Solution {
public:
    vector<vector<int>> getSkyline(vector<vector<int>>& buildings) {
        multiset<pair<int, int>> s;
        vector<vector<int>> res;
        
        for (auto& temp : buildings) 
        {
            s.insert(make_pair(temp[0], -temp[2])); // 左端点,高度入集合
            s.insert(make_pair(temp[1], temp[2])); // 右端点,高度入集合 
        }
        
        multiset<int> heights({0}); // 保存当前位置所有高度。
        vector<int> last = {0, 0}; // 保存上一个位置的横坐标以及高度
        for (auto& i : s) 
        {
            if (i.second < 0) heights.insert(-i.second); // 左端点,高度入堆
            else heights.erase(heights.find(i.second)); // 右端点,移除高度
            
            // 当前关键点,最大高度
            auto maxHeight = *heights.rbegin();
            
            // 当前最大高度如果不同于上一个高度,说明这是一个转折点
            if (last[1] != maxHeight) 
            {
                // 更新 last,并加入结果集
                last[0] = i.first;
                last[1] = maxHeight;
                res.push_back(last);
            }
        }
        
        return res;
    }
};

int main()
{
    int n,m;
    cin>>n;
    vector<vector<int>> buildings;
    for(int i=0;i<n;i++)
    {
        vector<int> row;
        for(int j=0;j<3;j++)
        {
            cin>>m;
            row.push_back(m);
        }
        buildings.push_back(row);
    }
    vector<vector<int>> res=Solution().getSkyline(buildings);
    for(int i=0;i<res.size();i++)
    {
        for(int j=0;j<2;j++)
        {
            if(j>0)
                cout<<" ";
            cout<<res[i][j];
        }
        if(i!=res.size()-1)
            cout<<endl;
    }
}
//mulset用法:https://blog.csdn.net/sodacoco/article/details/84798621

 

posted on 2020-09-15 21:20  Hi!Superman  阅读(271)  评论(0编辑  收藏  举报

导航