POJ4151 电影节
总时间限制:
1000ms
内存限制:
65536kB
描述:
大学生电影节在北大举办! 这天,在北大各地放了多部电影,给定每部电影的放映时间区间,区间重叠的电影不可能同时看(端点可以重合),问李雷最多可以看多少部电影。
输入:
多组数据。每组数据开头是n(n<=100),表示共n场电影。
接下来n行,每行两个整数(0到1000之间),表示一场电影的放映区间
n=0则数据结束
输出:
对每组数据输出最多能看几部电影
样例输入:
8
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
0
样例输出:
3
来源:
Guo Wei
题意分析:
由题目可知,要尽量看更多的电影,那么策略就是通过对电影时间进行某一种排序后,再进行贪心策略
下面给出两种方法:
方法一:
对电影结束时间进行从早到晚的排序,然后尽量选取结束早的电影看,以节省时间看后面的更多的电影。具体的操作方法是:对按结束时间排序后的电影从早到晚一个个遍历,若当前遍历到的这部电影的结束时间早于下一部电影的开始时间,则sum++(sum初始化为1,因为显然最少可以看一部电影),若当前遍历到的这部电影的结束时间完于下一部电影的开始时间,则看当前这部,不看下一部电影了(原因:对于重合的两场电影,当然选择结束早的,为后面留下更多的时间,这就是一种贪心思想)。
AC代码:
// An highlighted block
#include<bits/stdc++.h>
using namespace std;
struct node
{
int begin,end;//记录开始时间和结束时间
}a[105];
int cmp(node a,node b)
{
return a.end<b.end;//按结束时间由小到大排序
}
int main()
{
int t;
while((cin>>t)&&(t!=0))//数据组数
{
for(int i=0;i<t;i++)
{
scanf("%d%d",&a[i].begin,&a[i].end);//依次输入数据
}
sort(a,a+t,cmp);//排序
int sum=1;//最少看的电影书肯定是1
int js;//表示结束时间
js=a[0].end;
for(int i=1;i<t;i++)//依次遍历
{
if(a[i].begin>=js)//如果下一场开始的时间在这一场结束时间之后,就满足要求
{
js=a[i].end;//更新结束时间的值
sum++;//可以看电影的个数+1
}
}
printf("%d\n",sum);
}
}
方法二:
自己瞎想出来的野路子,没有第一种简洁,但方法还是挺有意思滴而且没有用到c++的知识(纯c实现的)。
大体思路是:利用a[x]=y储存开始时间和结束时间(x是开始时间,y为结束时间)。由于存在同一个开始时间对应着两场结束时间不一样的电影的情况,就要对这种情况下的电影进行取舍,和方法一的贪心策略一样,当然选择结束时间早的(如何选择时间少的呢,不妨让每次输入进来的x,y时,让a[x]与y对比,若a[x]>y,则将y赋值给a[x]以更新a[x])。同时每次输入一个x时,让q[x]++(在这操作前要对q[1005]全部初始化为0,以记录出现过哪些x)。
然后再搞一个rem[1005]数组,以记录x,记录方法为rem[1]=x1(x1为输入的x中第一小的x) rem[2]=x2 …………以此类推下去。
然后就剩代码中这部的理解了:
// An highlighted block
for(int i=1; i<=cnt-1; i++)//cnt是一共有几个不同的 x
{
if(a[rem[i]]<=rem[i+1])//情况1下面画图来解释
{
sum++;
}
else if(a[rem[i]]>=a[rem[i+1]]&&rem[i]<=rem[i+1])//情况2
{
continue;
}
else if(a[rem[i]]>=rem[i+1])//情况3
{
a[rem[i+1]]=a[rem[i]];
}
}
printf("%d\n",sum);
情况一:(上面的线是第i场电影的时间长度线 ,下面的是i+1场的时间长度线)
情况二:
情况三
下面是这个方法的AC完整代码:
// An highlighted block
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n!=0)
{
int a[1005];
int rem[1005]= {0};
for(int i=0; i<=1004; i++)
{
a[i]=9999;
}
int x,y;
int sum=1;
int q[1005]= {0};
for(int i=1; i<=n; i++)
{
scanf("%d%d",&x,&y);
if(x==y){sum++;}
q[x]++;
if(a[x]>y)
{
a[x]=y;
}
}
int cnt=0;
for(int i=0; i<=1000; i++)
{
if(q[i]!=0)
{
cnt++;
rem[cnt]=i;
}
}
for(int i=1; i<=cnt-1; i++)
{
if(a[rem[i]]<=rem[i+1])
{
sum++;
}
else if(a[rem[i]]>=a[rem[i+1]]&&rem[i]<=rem[i+1])
{
continue;
}
else if(a[rem[i]]>=rem[i+1])
{
a[rem[i+1]]=a[rem[i]];
}
}
printf("%d\n",sum);
}
return 0;
}