1. 程式人生 > 其它 >E - Third-Party Software - 2

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;
}