E - Third-Party Software - 2


一开始,我想的是按线段长度来排序,但是无法判断是否全覆盖1~m个区间
正确的作法应该先按开始端点升序,如果相等则末端点降序

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
struct node
{
    int a, b, id;
    friend bool operator <(const node &r, const node &w)
    {
        if(r.a != w.a)
        return r.a < w.a;
        else
        return r.b > w.b;
    }
}t[N];

vector<int> ans;
int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++)
        scanf("%d %d", &t[i].a, &t[i].b), t[i].id = i;
    
    sort(t + 1, t + 1 + n);
    if(t[1].a != 1)
    {
        cout << "NO\n";
        return 0;
    }
    ans.push_back(t[1].id);
    int j = t[1].b;
    for(int i = 2; i <= n;)
    {
        if(j >= t[i].a - 1)
        {
            int p = j, u = t[i].id;
            while(i <= n && j >= t[i].a - 1)//找出最优区间
            {
                if(t[i].b > p) //表示该区间不是已经选的区间的子集
                {
                    u = t[i].id;
                    p = t[i].b;
                }
                i++;
            }
            if(j == p)continue;
            j = p;
            ans.push_back(u);
        }
        else
        {
            cout << "NO\n";
            return 0;
        }
    }
    if(j < m)
    {
        cout << "NO\n";
        return 0;
    }
    cout << "YES\n" << ans.size() << endl;
    for(vector<int>::iterator it = ans.begin(); it != ans.end(); it++)
        printf("%d ", *it);
    printf("\n");
    return 0;
}
posted @ 2022-05-20 21:26  Flying_bullet  阅读(28)  评论(0)    收藏  举报