zoj3721Final Exam Arrangement(贪心)HNU训练赛六

/*http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5044
ZOJ Problem Set - 3721
Final Exam Arrangement
Time Limit: 4 Seconds      Memory Limit: 65536 KB      Special Judge
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


Author: CUI,Tianyi
Contest: ZOJ Monthly, June 2013
解析:
题意:有N门课,课程分布在[s,t)区间的时间点上,先进行期末考试,如何安排使得期末考试时间最短(注意
时间没有交集的课程不能放在同一天考试)
思路:
根据题意是要求有公共区间尽可能排在同一天,那么找公共区间是关键
1.这里用一组结构存储数据,并按照时间较早的顺序排列
2.在更新区间与寻找公共区间时记录时间
3.再根据时间先后及课程序号顺序在进行排序
                       
Run Time(ms) Run Memory(KB)
2013-07-20 16:33:20   1240 1748


*/
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include <iostream>
using namespace std;
const int maxn=100000+10;
struct course
{
int s;
int t;
int id;
int day;
}c[maxn];
bool cmp1(course a,course b)
{ return a.s<b.s||(a.s==b.s&&a.t<b.t);
}
bool cmp2(course  a,course b)
{
return a.day<b.day||(a.day==b.day&&a.id<b.id);
}
int main()
{int i,j,n,ans;
while(scanf("%d",&n)!=EOF)
{ int x,y;
for(i=0;i<n;i++)
  {scanf("%d%d",&x,&y);
   c[i].s=x;
   c[i].t=y;
   c[i].id=i+1;
   c[i].day=0;
  }
  sort(c,c+n,cmp1);//根据起点时间较早的情况排序
   ans=1;
    int tt=c[0].t;
int ts=c[0].s;
c[0].day=1;
   for(i=1;i<n;i++)
     {
      while(i<n&&c[i].s<tt)//如果有交集的话,更新区间,变当前区间为公共区间,一直传递下去找
       {c[i].s=ts>c[i].s? ts:c[i].s;
        c[i].t=tt<c[i].t? tt:c[i].t;
        tt=c[i].t;
        ts=c[i].s;
        c[i].day=ans;
        i++;
       }
       if(i<n)
       {ans++;
        tt=c[i].t;
        ts=c[i].s;
        c[i].day=ans;
       }
     }
     printf("%d\n",ans);
     sort(c,c+n,cmp2);//第二次排序
     int d=c[0].day;
     printf("%d",c[0].id);
     for(i=1;i<n;i++)
      {while(c[i].day==d&&i<n)
        {printf(" %d",c[i].id);
         i++;
        }
        if(i<n)
        {printf("\n");
        d=c[i].day;
        printf("%d",c[i].id);
        }
      }
      printf("\n\n");
 }
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值