本题可以采用优先队列的方法来写
一开始我们定义cows数组,要能存储3个值,可以这样定义pair< PII, int > cows[N], 输入时这样输入 cin >> cows[i].first.first >> cows[i].first.second; 再将坐标放在cows[i].second中
开一个优先队列 priority_queue< PII, vector< PII >, greater< PII > > heap;每次取顶,就是它里面存放的所有数的最小值,我们一次取出它里面的最小值与下一头牛比较,如果heap里面存放的最小值的牛喝水终止值比新来的牛起始值早或相等,则我们只能将新来的牛另开一栏, 反之,我们新来的牛可以用heap存放最小值的那个牛用的围栏喝水,一共用了多少围栏就是heap存放了几组数据
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 50010;
int n;
pair<PII, int> cows[N];
int id[N];
int main()
{
cin >> n;
//先存每头牛起始值和终止值, 再存下标
for (int i = 0; i < n; i ++ )
{
cin >> cows[i].first.first >> cows[i].first.second;
cows[i].second = i;
}
//以起始值排序
sort(cows, cows + n);
//定义一个优先队列heap,heap.top会优先输出它里面的最小值
//这里heap.first是输入进来的牛喝水的终止值,heap.second为这牛在哪个牛栏
priority_queue<PII, vector<PII>, greater<PII>> heap;
for (int i = 0; i < n; i ++ )
{
auto cow = cows[i].first;//取出坐标
//需要再开一栏
if (heap.empty() || heap.top().first >= cow.first)
{
PII stall = {cow.second, heap.size() + 1};
heap.push(stall);
id[cows[i].second] = stall.second;
}
//不需要重开,可以接在其他牛后面
else
{
auto stall = heap.top();
heap.pop();
id[cows[i].second] = stall.second;
heap.push({cow.second, stall.second});
}
}
cout << heap.size() << endl;
for (int i = 0; i < n; i ++ )
cout << id[i] << endl;
}