BNUOJ 33535 Final Exam Arrangement

In Zhejiang University, there are N different courses labeled from 1 to N. Each course has its own time slot during the week. We can represent the time slot of a course by an left-closed right-open interval [s, t).

Now we are going to arrange the final exam time of all the courses.

The final exam period will contain multiple days. In each day, multiple final exams will be held simultaneously. If two courses' time slots are not overlapped, there may be students who are attending both of them, so we cannot arrange their final exams at the same day.

Now you're to arrange the final exam period, to make the total days as small as possible.

Input

There are multiple test cases separated by blank lines.

For each ease, the 1st line contains one integer N(1<=N<=100000).

Then N lines, the i+1th line contains s and t of the interval [s, t) for the ith course.(0<=s<t<=231-1)

There is a blank line after each test case.

Output

For each case, the 1st line contains the days P in the shortest final exam period.

Next P lines, the i+1th line contains the numbers of courses whose final exam is arranged on the ith day separated by one space.

Output a blank line after each test case.

Sample Input

4
0 1
1 2
2 3
3 4

4
0 2
1 3
2 4
3 5

4
0 4
1 5
2 4
3 6

Sample Output

4
1
2
3
4

2
1 2
3 4

1
1 2 3 4

 

Source 

Author 

CUI,Tianyi
 
 
 
 
【题意】:
  就是说一个课程有l,r,其范围是【l,r);如果课程与一个集合里面的所有元素都存在交集,就可以丢到一个集合里面
 问最少要几个集合?
 
【思路】:
  先按照l升序排序,再按照r降序排序,然后按照一个一个去取,那么每次取的时候更新temp的l,r。r取min值,l取max值,
就是每次能找到的最小集合区间。如果不能满足,那么久更新temp的值为新的区间,再往下寻找。这样最后就能统计出结果
  为什么这样贪心具有合理性呢?
假设有一个区间,那么我们取出符合区间的一段l最小,r最大的去寻找,寻找出来的子集有可能不是最多的,但是是合理的。如果
你去寻找最多的话,那么肯定不在这个区间,那么这个区间就得另外独立出来,一样的就会多出一个集合,那么这样分类都是无所谓的
我们只需要,选择l最小r最大这样一直下去,所有的子状态肯定都是满足的
 
 
附上代码
 
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
/**
简直有毒,行末空格wa一天
 **/
using namespace std;
const int MAXN = 100000 + 5;
typedef long long ll;
inline void Read(ll &x)
{
    x=0;
    static char ch=getchar();
    while (ch<'0'||ch>'9')
        ch=getchar();
    while (ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
}
typedef  struct NODE
{
    int num;
    ll l, r;
}node;
node arr[MAXN];
inline bool cmp(const node &a, const node &b)
{
    if(a.l != b.l)
    {
        return a.l < b.l;
    }
    else
    {
        return a.r > b.r;
    }
    return -1;
}
inline bool judge(const node &a, const node &b)
{
    if(b.l < a.r)
        return true;
    else
        return false;
}
vector<int>vec[MAXN];
int n;
int main()
{
    //freopen("test.in"  ,"r",stdin);
    //freopen("test1.out","w",stdout);
    int sum, num;
    while(~scanf("%d", &n))
    {
        sum = num = 0;
        for(int i = 0; i < n; i ++)
        {
            vec[i].clear();
        }
        memset(arr, 0, sizeof(arr));
        for(int i = 0; i < n; i ++)
        {
            //scanf("%lld%lld", &arr[i].l, &arr[i].r);
            Read(arr[i].l);
            Read(arr[i].r);
            arr[i].num = i + 1;
        }
        sort(arr, arr + n, cmp);
        node temp = arr[0];
        int num, sum;
        num = sum = 0;
        for(int i = 0; i < n; i ++)
        {
            if(judge(temp, arr[i]))
            {
                temp.l = max(temp.l, arr[i].l);
                temp.r = min(temp.r, arr[i].r);
                vec[num].push_back(arr[i].num);
            }
            else
            {
                temp = arr[i];
                sum ++;
                num ++;
                vec[num].push_back(arr[i].num);
            }
        }
        printf("%d\n", sum + 1);
        for(int i = 0; i < num + 1; i ++)
        {
            for(int j = 0; j < vec[i].size(); j ++)
            {
                if(j != vec[i].size() - 1)
                printf("%d ", vec[i][j]);
                else
                    printf("%d", vec[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qq136155330/p/10201159.html