047.扫描线

扫描线

对边界排序,按顺序扫描,过程中动态维护当前位置状态,从而高效处理区间问题

经典扫描线问题,天际线

leetcode 218

class Solution {
public:
    vector<vector<int>> getSkyline(vector<vector<int>>& buildings) {
        set<int>st;
        for(auto x:buildings){
            st.insert(x[0]);
            st.insert(x[1]);
        }
        priority_queue<pair<int,int>>pq;
        // first :: 高度
        // second :: 区间右端点(区间结束时间)
        int i=0;
        vector<vector<int>>ans;
        int pre=-1,h;
        for(auto cur:st){
            // cur :: 当前处理的线
            while(i<(int)buildings.size()&&buildings[i][0]<=cur){//包含当前扫描线的区间入堆
                pq.push({buildings[i][2],buildings[i][1]-1});
                i++;
            }
            while(pq.size()&&pq.top().second<cur)pq.pop();//堆顶过期则弹出
            h=pq.size()?pq.top().first:0;
            if(h!=pre){
                ans.push_back({cur,h});
            }
            pre=h;
        }
        return ans;
    }
};

luogu P1904

#include<bits/stdc++.h>

using namespace std;
typedef pair<int,int> pii;

void solve(){
    int L,H,R;
    vector<vector<int>>a;
    while(cin>>L>>H>>R){
        a.push_back({L,R,H});
    }
    sort(a.begin(),a.end(),[](auto &x,auto &y){return x[0]<y[0];});
    set<int>st;
    for(auto x:a){
        st.insert(x[0]);
        st.insert(x[1]);
    }
    priority_queue<pii>pq;
    int i=0;
    int pre=-1,h;
    for(auto cur:st){
        while(i<(int)a.size()&&a[i][0]<=cur){
            pq.push({a[i][2],a[i][1]-1});
            ++i;
        }
        while(pq.size()&&pq.top().second<cur)pq.pop();
        h=pq.size()?pq.top().first:0;
        if(h!=pre){
            cout<<cur<<' '<<h<<' ';
        }
        pre=h;
    }
}
int main(void){
    cin.tie(0)->sync_with_stdio(0);
    int T=1;
    //cin>>T;
    while(T--)solve();
}

类似问题

leetcode 1851

class Solution {
public:
    vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries) {
        vector<pair<int,int>>Q;
        int n=queries.size();
        for(int i=0;i<n;++i){
            Q.push_back({queries[i],i});
        }
        ranges::sort(Q);
        sort(intervals.begin(),intervals.end(),[](auto a,auto b){return a[0]<b[0];});
        priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>>pq;
        int i=0;
        vector<int>ans(n);
        for(auto [cur,id]:Q){
            while(i<(int)intervals.size()&&intervals[i][0]<=cur){
                pq.push({intervals[i][1]-intervals[i][0]+1,intervals[i][1]});
                ++i;
            }
            while(pq.size()&&pq.top().second<cur)pq.pop();
            ans[id]=pq.size()?pq.top().first:-1;
        }
        return ans;
    }
};
posted @ 2026-01-16 18:42  射杀百头  阅读(0)  评论(0)    收藏  举报