poj 3190 Stall Reservations

题目链接http://poj.org/problem?id=3190


花了好长时间卡了很久,在贵人的指点下终于过了。


题目大意:有n头牛,每头牛都有特定的取奶时间段且相互之间不能有重叠,取奶场所为畜栏,现在要给所有乳牛取奶,要求求出最少的畜栏数并列出每头牛对应的畜栏位置。


思路:先以开始时间小到大排序,用当前最早开始的结束时间为新的扩充起点,继续往下找开始时间比它晚的。每找到一个删除一个。


这是贪心的区间问题,每次找比当前晚且离当前最近的点(前提是没有重叠部分)。



注意:问题规模比较大,如果用枚举比较来查找的话可能会超时,可以用set,其查找的时间复杂度相当可观。但是一开始忽略了set不能有相同的元素这点,想要有相同元素可以用multiset。

还可以锻炼对set的应用



#include<iostream>
using namespace std;
#include<set>
#include<algorithm>
#define maxn 50005
struct point{
 int x,y,id;
 bool operator <(point a)const
 {
	 return x<a.x;//重载小于号
 }
};
multiset<point> t;
point p;
int num[maxn];
int main()
{
	int n,m=0;
	while(scanf("%d",&n)!=EOF)
	{
		point temp;
		memset(num,-1,sizeof(num));
		int a;
		for(a=0;a<n;a++)
		{
			scanf("%d%d",&p.x,&p.y);
			p.id=a;
			t.insert(p);
		}
		multiset<point>::iterator i;
		a=1;
		while(!t.empty())
		{
			temp.x=t.begin()->y;//以最早点的结束时间为新的扩充起点
			i=t.upper_bound(temp);//找开始时间比temp.x晚的点
			while(i!=t.end())
			{
				temp.x=i->y;
				num[i->id]=a;//记录位置
				t.erase(i);//删除
				i=t.upper_bound(temp);
			}
			num[t.begin()->id]=a++;
			t.erase(t.begin());
		}
		printf("%d\n",a-1);
		for(a=0;a<n;a++)
			printf("%d\n",num[a]);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值