1. 程式人生 > 實用技巧 >【YBTOJ】畜欄預定

【YBTOJ】畜欄預定

題目大意:

\(n\) 頭牛在畜欄中吃草。每個畜欄在同一時間段只能提供給一頭牛吃草,所以可能會需要多個畜欄,給出第 \(i\) 頭牛開始吃草的時間區間 \([l_i,r_i]\),求需要的最少的畜欄數和每頭牛對應的畜欄方案。

正文:

這道題非常簡單,只用順著題目來就行了。

先將牛牛按 \(l\) 排好序。接下來列舉到第 \(i\) 頭,先在已有的畜欄裡找有沒有哪頭牛牛吃完了草。如果有,則當前牛子就佔它的位置;如果沒有,牛子就到新畜欄去。

這個過程當然可以用堆來實現。按照牛子們的 \(r\) 作為 key。

程式碼:

const int N = 50010;

int n, ans[N], cnt = 1;
struct node
{
	int l, r, id;
}a[N];

struct que
{
	int id, r;
	const bool operator < (const que &b) const
	{
		return r > b.r;
	}
};

priority_queue <que> q;

bool cmp (node a, node b)
{
	if (a.l == b.l) return a.r < b.r;
	return a.l < b.l;
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		scanf ("%d%d", &a[i].l, &a[i].r), a[i].id = i;
	sort (a + 1, a + 1 + n, cmp);
	q.push((que){1, a[1].r});
	ans[a[1].id] = 1;
	for (int i = 2; i <= n; i++)
	{
		que t = q.top();
		if (t.r >= a[i].l)
		{
			cnt++;
			ans[a[i].id] = cnt;
			q.push((que){cnt, a[i].r}) ;
		}
		else
		{
			q.pop();
			ans[a[i].id] = t.id;
			q.push((que){t.id, a[i].r});
		}
	}
	printf ("%d\n", cnt);
	for (int i = 1; i <= n; i++)
		printf ("%d\n", ans[i]);
}