[CF35E] Parade

[CF35E] Parade - 扫描线

Description

给出 n 个底边在 x 轴上的矩形,求外面的轮廓线顶点。

Solution

考虑扫描线,用一个 multiset 维护当前穿过的所有矩形

一个矩形转化为两个事件:添加一个数和删除一个数

如果操作完后集合的 max 和操作之前不同,那么它就会贡献两个顶点

#include <bits/stdc++.h>
using namespace std;

signed main()
{
    ios::sync_with_stdio(false);
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    vector<pair<int, int>> vec;
    for (int i = 0; i < n; i++)
    {
        int h, x, y;
        cin >> h >> x >> y;
        vec.push_back({x, h});
        vec.push_back({y, -h});
    }
    sort(vec.begin(), vec.end());
    vector<pair<int, int>> ans;
    multiset<int> ms;
    ms.insert(0);
    for (int l = 0; l < vec.size();)
    {
        int r = l;
        int h_o = *ms.rbegin();
        while (r < vec.size() && vec[l].first == vec[r].first)
        {
            auto [x, h] = vec[r];
            if (h > 0)
                ms.insert(h);
            else
                ms.erase(ms.find(-h));
            ++r;
            if (r > 2 * n)
                break;
        }
        int h_n = *ms.rbegin();
        if (h_o != h_n)
        {
            ans.push_back({vec[l].first, h_o});
            ans.push_back({vec[l].first, h_n});
        }
        l = r;
    }
    cout << ans.size() << endl;
    for (auto [x, y] : ans)
        cout << x << " " << y << endl;
}
原文地址:https://www.cnblogs.com/mollnn/p/14412089.html