Canvas Line

链接 : https://codeforces.com/gym/102500/problem/C

题意 :

给出 n 个区间, m 个点, 要求加入最少的点使得每个区间中恰好包含 2 个点.

思路 :

贪心, 先处理给出的 m 个点, 标记它们的位置, 然后考虑加点的方式 :

​ 1) 若该区间有 2 个点了, continue.

​ 2) 若该区间正好 1 个点, 若能在其右端点加点(要保证该位置未被标记且下一个区间不会因为该操作点数超过 2), 必在其加点. 若右端点已被标记或不能在这加点, 则从右端点往后找一个可加的点加上.

​ 3) 若该区间 0 个点, 必能在右端点 - 1 处加点, 右端点能加必加, 不能加则在 右端点 - 2 处加点.

代码 :
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
inline int lowbit(int x) { return x & (-x); }
#define ll long long
#define pb push_back
#define PII pair<int, int>
#define fi first
#define se second
#define inf 0x3f3f3f3f
const int N = 1e3 + 7;
unordered_map<int, int> st;
int a[2 * N];

struct node {
    int l, r, cnt;
    bool operator < (const node& t) const {
        return l < t.l;
    }
}p[N];

int main() {
    IO;
    int n, m, x;
    cin >> n;
    for (int i = 1; i <= n; ++i) cin >> p[i].l >> p[i].r;
    sort(p + 1, p + 1 + n);
    cin >> m;
    for (int i = 1; i <= m; ++i) {
        cin >> a[i];
        st[a[i]] = 1;
    }
    
    for (int i = 1, j = 1; i <= m; ++i) {
        while (a[i] > p[j].r && j <= n) j++;
        if (a[i] >= p[j].l) {
            p[j].cnt++;
            if (p[j].r == p[j + 1].l && a[i] == p[j].r) p[j + 1].cnt++;
        }
    }
    
    for (int i = 1; i <= n; ++i)
        if (p[i].cnt > 2) {
            cout << "impossible\n";
            return 0;
        }
     
    vector<int> ans;
    for (int i = 1; i <= n; ++i) {
        if (p[i].cnt == 1) {
            if (st[p[i].r]) ans.pb(p[i].r - 1);
            else {
                if (p[i].r == p[i + 1].l && p[i + 1].cnt < 2) {
                    ans.pb(p[i].r);
                    p[i + 1].cnt++;
                } else {
                    int pos = p[i].r - 1;
                    while (st[pos]) pos--;
                    ans.pb(pos);
                }
            }
        } else if (p[i].cnt == 0) {
            ans.pb(p[i].r - 1);
            if (p[i].r == p[i + 1].l && p[i + 1].cnt < 2) {
                    ans.pb(p[i].r);
                    p[i + 1].cnt++;
                } else ans.pb(p[i].r - 2);
        }
    }

    cout << ans.size() << endl;
    for (auto t : ans) cout << t << " ";
    return 0;
}

posted @ 2020-11-22 22:16  phr2000  阅读(236)  评论(0编辑  收藏  举报