您的位置:首页 > 理论基础 > 数据结构算法

Codeforces 31C Schedule(数据结构)

2016-04-26 00:33 603 查看
Schedule

time limit per test2 seconds

memory limit per test256 megabytes

inputstandard input

outputstandard output

At the beginning of the new semester there is new schedule in the Berland State University. According to this schedule, n groups have lessons at the room 31. For each group the starting time of the lesson and the finishing time of the lesson are known. It has turned out that it is impossible to hold all lessons, because for some groups periods of their lessons intersect. If at some moment of time one groups finishes it’s lesson, and the other group starts the lesson, their lessons don’t intersect.

The dean wants to cancel the lesson in one group so that no two time periods of lessons of the remaining groups intersect. You are to find all ways to do that.

Input

The first line contains integer n (1 ≤ n ≤ 5000) — amount of groups, which have lessons in the room 31. Then n lines follow, each of them contains two integers li ri (1 ≤ li < ri ≤ 106) — starting and finishing times of lesson of the i-th group. It is possible that initially no two lessons intersect (see sample 1).

Output

Output integer k — amount of ways to cancel the lesson in exactly one group so that no two time periods of lessons of the remaining groups intersect. In the second line output k numbers — indexes of groups, where it is possible to cancel the lesson. Groups are numbered starting from 1 in the order that they were given in the input. Output the numbers in increasing order.

Examples

input

3

3 10

20 30

1 3

output

3

1 2 3

input

4

3 10

20 30

1 3

1 39

output

1

4

input

3

1 5

2 6

3 7

output

0

题目大意:

就是n个组要在某个教室上课,但是上课时间不能重叠,问去掉一个组的课程就可以使得其他n-1个组的课程不重叠的方案有几种,并按照从小到大的顺序输出这些组号

题目分析:

最开始以为是贪心中的区间问题,但是后来发现这个就是一道数据结构的设计问题,我是这样设计的,一个四元组来存储每个组的信息

{组号,开始时间,结束时间,重叠次数}

这里的重叠次数指的是当前组和其他组的重叠的次数

然后对这n个组的信息按照起始时间进行从小到大的排序,

接下来就开始要对每个组的重叠次数进行统计,如果相邻两个组的时间没有重叠,那么他们两个组的重叠次数没有变化,如果相邻两个组有重叠,并且第三个组跟着两个组的重叠部分没有公共部分的话,那么对每个组的重叠次数加上1,整个的重叠次数也减去1

在接下来就是搜结果了,如果整个的重叠次数减去当前组的重叠次数等于零的话,说明去掉当前组的话可以满足条件,那么就把当前的组号压进优先队列,如果不是0,就不满足啦

当然我这里说的只是思路,具体实现的话需要细节支持,接下来看代码吧。

代码:

#include "stdio.h"
#include "algorithm"
#include "string.h"
#include "queue"
using namespace std;
struct node
{
int l,r,c,no;
};
node t[5000+5];

bool cmp(node a,node b)
{
if(a.l==b.l) return a.r<b.r;
return a.l<b.l;
}
int main()
{
int n,i,total,res;
while(scanf("%d",&n)!=EOF)
{
memset(t,0,sizeof(t));
for(i=0;i<n;i++)
{
scanf("%d%d",&t[i].l,&t[i].r);
t[i].c=0;
t[i].no=i+1;
}
sort(t,t+n,cmp);
total=res=0;
int r=t[0].r,cur=0;
bool flag=false;
for(i=1;i<n;i++)
{
//cur指的是当前与后面组进行比较的组,含义的话只能去体会了
if(t[i].l<r){
if(i<n-1&&t[i+1].l<min(r,t[i].r)){
flag=true;
break;
}else{
t[cur].c++;
t[i].c++;
if(t[i].r>=r){
cur=
4000
i;
r=t[i].r;
}
total++;
}
}else{
cur=i;
r=t[i].r;
}
}
if(flag){
printf("0\n");
}else{
priority_queue<int,vector<int>,greater<int> > que;
for(i=0;i<n;i++)
{
//printf("%d\n",t[i].c);
if(total-t[i].c==0){
que.push(t[i].no);
res++;
}
}
printf("%d\n",res);
while(!que.empty()){
if(que.size()!=1){
printf("%d ",que.top());
}else{
printf("%d\n",que.top());
}
que.pop();
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces 数据结构