畜栏保留解法二


#include<iostream>
using namespace std;
#include<queue>
#include<algorithm>
//畜栏问题2

//Stall 畜栏结构体
struct Stall {
	int end;//结束时间
	int no;//畜栏编号
	bool operator<(const Stall& b)const
	{
		return this->end > b.end;   //优先队列排列时,>表示小顶堆,表示 按照结构体中的 end成员从小到大排列
	}
	Stall(int e, int n) :end(e), no(n) {}
};
//Cow 奶牛结构体
struct Cow {
	int l;
	int r;
	int no;//奶牛的编号
	bool operator<(const Cow& b)const {//用于快速排序 ,按照<  表示按照奶牛挤奶时间段的左端点 l从小到大排序 ,下面将调用sort()排列
		return this->l < b.l;
	}
};

Cow cows[7];
int num[7];//编号为i的奶牛对应的畜栏编号 因为奶牛是逐一处理的所以这个num与畜栏一一对应
int total = 0; //当前的畜栏个数
//
//想法:先把牛按照从小到大的起始时间排列,按照挤奶开始时间排列 
//把畜栏按照结束时间从小到大排列---优先队列,先出队列的是最早结束的
// 开始时,队列为空total=0,畜栏数目,队列元素个数为0 先加1,畜栏的结束时间为加入的牛挤奶结束时间,编号就是此时畜栏的数目
// 比较阶段 当q.top().end<cow[i].l 最早可以空出的畜栏时间小于 当前开始要处理的奶牛,Stall s=q.top(),再把这个畜栏pop()出来,把它的end 设置为 cows[i].r  ,no序号保持不变 ,把cows[i].num设置为s.no
//当q.top().end>=cow[i].l ,新建一个畜栏 total++;q.push(Stall(a[i].r,total)) 

int main() {
	int n;//输入奶牛个数
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> cows[i].l >> cows[i].r;
		cows[i].no = i;
	}
	sort(cows, cows + n); //按照挤奶开始时间排列  从小到大
	priority_queue<Stall> q; // 建立关于Stall的优先队列  按照结束时间从早到晚排列
	for (int i = 0; i < n; i++)
	{
		if (q.empty())  //只执行一次
		{
			total++;
			q.push(Stall(cows[i].r, total));
			num[cows[i].no] = total;
		}
		else
		{
			Stall s = q.top();
			if (s.end < cows[i].l)
			{
				q.pop();
				num[cows[i].no] = s.no;
				q.push(Stall(cows[i].r, s.no));
			}
			else //q.top().end >= cows[i].l
			{
				total++;
				q.push(Stall(cows[i].r, total));
				num[cows[i].no] = total;
			}
		}
	}
	cout << total << endl;

	for (int i = 0; i < n; i++)
		cout << num[i] << endl;  //这里一开始我写的是cows[i].num呜呜呜这个bug找了好久
	return 0;
	// 因为这里还是要按照一开始输入的顺序输出各个奶牛对应的栅栏
//而前面sort排序后cows[i]的顺序已经是按照开始时间排序的,这里可以通过调试发现,所以要想按照之前的排序输出,i应该换为cows[i].no
	//no是初始顺序0,1,2,3,4。。。
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值