Stall Reservations POJ

原题链接

经典贪心题目。
思路:开结构体cow、stall分别表示牛、畜栏,其中,每个cow都有编号、开始挤奶、结束挤奶时间,每个stall都有编号、当前在该畜栏中挤奶的牛的挤奶结束时间。

struct cow {
    
    
    int st, ed; // 牛开始、结束挤奶的时间
    int cno; // 牛的编号
    cow () {
    
    }
    cow (int s, int e) : st(s), ed(e) {
    
    }

    bool operator < (const cow &b) const {
    
    
        if (st != b.st) return st < b.st;
        else return ed < b.ed;
    }
} niu[50010];

struct stall {
    
    
    int sno; // 畜栏的编号
    int sed; // 该畜栏结束挤奶时间

    stall () {
    
    }
    stall (int _sno, int _sed) : sno(_sno), sed(_sed) {
    
    }

    bool operator < (const stall &b) const {
    
    
        return sed > b.sed;
    }
};

并且,要将牛按照挤奶开始时间从小到大排序,如果开始挤奶时间相同,则按照挤奶结束时间从小到大排序。
在stall中,重载运算符,为了使用优先队列,立即得到当前所有畜栏中,最早结束挤奶的畜栏编号。
比如说,当前有畜栏1,2,3,共三个,每个畜栏结束挤奶的时间分别是100,200,300。当前又有一只牛,要在90时刻挤奶,则它不能去这三个任何一个,因为,这三个畜栏在90时刻都有牛在挤奶。只能另开畜栏。
AC代码:

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
using namespace std;

int n;
int pos[50010]; // 每头牛去往的畜栏编号

struct cow {
    
    
    int st, ed; // 牛开始、结束挤奶的时间
    int cno; // 牛的编号
    cow () {
    
    }
    cow (int s, int e) : st(s), ed(e) {
    
    }

    bool operator < (const cow &b) const {
    
    
        if (st != b.st) return st < b.st;
        else return ed < b.ed;
    }
} niu[50010];

struct stall {
    
    
    int sno; // 畜栏的编号
    int sed; // 该畜栏结束挤奶时间

    stall () {
    
    }
    stall (int _sno, int _sed) : sno(_sno), sed(_sed) {
    
    }

    bool operator < (const stall &b) const {
    
    
        return sed > b.sed;
    }
};

int main()
{
    
    
    scanf("%d", &n);

    for (int i = 1;i <= n;i++) {
    
    
        scanf("%d %d",&niu[i].st, &niu[i].ed);
        niu[i].cno = i;
    }

    sort(niu+1,niu+n+1);
    
    int cnt = 1;
    priority_queue<stall> q;
    pos[niu[1].cno] = cnt;  // 第一个牛去往1号畜栏
    q.push(stall(1,niu[1].ed)); // 将1号畜栏入队

    for (int i = 2;i <= n;i++) {
    
     // 依次处理之后的牛
        int st = niu[i].st; // 该牛挤奶时间
        int ed = niu[i].ed; // 该牛挤奶结束时间
        
        // 如果当前最早结束挤奶的畜栏的结束时间小于该牛开始挤奶时间,该牛去往该畜栏
        if (q.top().sed < st) {
    
      // 不可以是 <= 
            stall cur = q.top();
            q.pop();
            pos[niu[i].cno] = cur.sno;
            cur.sed = ed;
            q.push(cur);
        } else {
    
     // 当前牛的开始挤奶时间,比任何畜栏的结束时间都早或者等于最早结束挤奶的畜栏的挤奶时间,只能再开一个畜栏
            cnt++;
            pos[niu[i].cno] = cnt;
            q.push(stall(cnt,ed));
        }
    }
    printf("%d\n",cnt);
    for (int i = 1;i <= n;i++) {
    
    
        printf("%d\n",pos[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44321570/article/details/123441911