清洁牛棚——逻辑思考


问题描述:

Farmer John is assigning some of his N (1 <= N <= 25,000) cows to do some cleaning chores around the barn. He always wants to have one cow working on cleaning things up and has divided the day into T shifts (1 <= T <= 1,000,000), the first being shift 1 and the last being shift T.

Each cow is only available at some interval of times during the day for work on cleaning. Any cow that is selected for cleaning duty will work for the entirety of her interval.

Your job is to help Farmer John assign some cows to shifts so that (i) every shift has at least one cow assigned to it, and (ii) as few cows as possible are involved in cleaning. If it is not possible to assign a cow to each shift, print -1.

Input

* Line 1: Two space-separated integers: N and T

* Lines 2..N+1: Each line contains the start and end times of the interval during which a cow can work. A cow starts work at the start time and finishes after the end time.

Output

* Line 1: The minimum number of cows Farmer John needs to hire or -1 if it is not possible to assign a cow to each shift.


样例输入:

3 10
1 7
3 6
6 10


样例输出:

2


题目分析:

第一行两个数,一个是多少班母牛工作,第二个是牛棚数量。

接下来是每一班的工作区间。

求几班母牛,能把所有的牛棚清理完。

例如:该样例选择 1 7,6 10。两班就能包含1——10所有的牛棚。

如果没有答案,输出-1.


思路分析:

首先要包含1——n,如果数据中没有1或没有n,则肯定没有答案,要输出-1.

如果有一个区间是1——n或大于n的数,则只需要这1组就可以了。

特殊情况考虑完了,要看一般情况了。

首先应对给出的区间数据,以第一个数为标准,从小到大的排序。

14
36
78

以上是自己随便出的排好序的数据,第一个数据一定是开头为1的数据,这个肯定要选。

然后要先考虑后一个数的大小,

6>4,所以我们要考虑要不要选这一组,根据3和4的关系,3这个位置上的数最大应为5(4+1),这样才能把两个区间都选,并且不漏掉数。如果3是6的话,前两组就包含不了5.

则肯定不能全部包括,就输出-1。

然后要用6去和下一组的右侧的数比较,这里就是8.

如果6是3,3<4的话,就不需要考虑这一组了,因为第一组可以包含到4,第二组的所有数肯定已经被第一组包含了。

如果遍历完每一组数后,最后一组的数据右侧的数仍小于n,则就要输出-1。

所以我们只需要用代码模拟这个过程,就可以了,注意要更新比较的值,这里就是6,8。


解决方案:

#include "stdio.h"
#include "string.h"
#include "algorithm"
using namespace std;
struct note 
{
	int x,y;
}t[110000];
bool cmp(note a,note b)
{
	if(a.x==b.x)
	return a.y<b.y; 
	return a.x<b.x;
} 
int main ()
{
	int s,ans;
	int m,n,i,j;
	scanf("%d%d",&n,&m);
	for(i=0;i<n;i++)
	scanf("%d%d",&t[i].x,&t[i].y);
	sort(t,t+n,cmp);//排序 
    //特殊情况 
	 if(t[0].x==1&&t[0].y>=m)
    printf("1\n");
    else if(t[0].x!=1)
    printf("-1\n");
   //
   //一般情况 
    else
    {
      s=t[0].y;//初始化 
      ans=1;
      for(i=1;i<n&&s<m;)
      {
      	ans++;
      	int g=s;
      	if(t[i].x>s+1)//判断会不会漏数,类似4,3,6这种 
      	{
      		printf("-1\n");
      		return 0;
		}
      	while(i<n&&t[i].x<=s+1)
      	{
      		g=max(g,t[i].y);
      		i++;
		  }
		  s=g;	//更新比较的值 
	  }
	  //最后一组,最右侧的数小于m. 
	  if(s<m)
	  printf("-1\n");
	  else
	  printf("%d\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值